<!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> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="globals.html">Globals</a> <a class="qindex" href="pages.html">Related Pages</a> </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 <stdarg.h></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) && !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 <sys/types.h></span> 00020 <span class="preprocessor">#include <errno.h></span> 00021 <span class="preprocessor">#include <fcntl.h></span> 00022 <span class="preprocessor">#include <getopt.h></span> 00023 <span class="preprocessor">#include <stdio.h></span> 00024 <span class="preprocessor">#include <stdlib.h></span> 00025 <span class="preprocessor">#include <string.h></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 <<a class="code" href="rpmio__internal_8h.html">rpmio_internal.h</a>></span> 00046 <span class="preprocessor">#include <<a class="code" href="rpmmessages_8h.html">rpmmessages.h</a>></span> 00047 <span class="preprocessor">#include <<a class="code" href="rpmerr_8h.html">rpmerr.h</a>></span> 00048 00049 <span class="preprocessor">#endif</span> 00050 <span class="preprocessor"></span> 00051 <span class="preprocessor">#include <<a class="code" href="rpmmacro_8h.html">rpmmacro.h</a>></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> = &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> = &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)->t = (_c), (_mb)->t++, (_mb)->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 && 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-><a class="code" href="structMacroEntry__s.html#m1">name</a>, bme-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a> == NULL) { 00161 mc-><a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a> = <a class="code" href="macro_8c.html#a5">MACRO_CHUNK_SIZE</a>; 00162 mc-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>)) * mc-><a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a>); 00164 mc-><a class="code" href="structMacroContext__s.html#m2">firstFree</a> = 0; 00165 } <span class="keywordflow">else</span> { 00166 mc-><a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a> += <a class="code" href="macro_8c.html#a5">MACRO_CHUNK_SIZE</a>; 00167 mc-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>, <span class="keyword">sizeof</span>(*(mc-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>)) * 00169 mc-><a class="code" href="structMacroContext__s.html#m1">macrosAllocated</a>); 00170 } 00171 memset(&mc-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>[mc-><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-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a> == NULL) 00185 <span class="keywordflow">return</span>; 00186 00187 qsort(mc-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>, mc-><a class="code" href="structMacroContext__s.html#m2">firstFree</a>, <span class="keyword">sizeof</span>(*(mc-><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 < mc-><a class="code" href="structMacroContext__s.html#m2">firstFree</a>; i++) { 00192 <span class="keywordflow">if</span> (mc-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i] != NULL) 00193 <span class="keywordflow">continue</span>; 00194 mc-><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-><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 < mc-><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-><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-><a class="code" href="structMacroEntry__s.html#m5">level</a>, 00219 (me-><a class="code" href="structMacroEntry__s.html#m4">used</a> > 0 ? <span class="charliteral">'='</span> : <span class="charliteral">':'</span>), me-><a class="code" href="structMacroEntry__s.html#m1">name</a>); 00220 <span class="keywordflow">if</span> (me-><a class="code" href="structMacroEntry__s.html#m2">opts</a> && *me-><a class="code" href="structMacroEntry__s.html#m2">opts</a>) 00221 fprintf(fp, <span class="stringliteral">"(%s)"</span>, me-><a class="code" href="structMacroEntry__s.html#m2">opts</a>); 00222 <span class="keywordflow">if</span> (me-><a class="code" href="structMacroEntry__s.html#m3">body</a> && *me-><a class="code" href="structMacroEntry__s.html#m3">body</a>) 00223 fprintf(fp, <span class="stringliteral">"\t%s"</span>, me-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a> == NULL || mc-><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 > 0) { 00254 strncpy(namebuf, name, namelen); 00255 namebuf[namelen] = <span class="charliteral">'\0'</span>; 00256 name = namebuf; 00257 } 00258 00259 key = &keybuf; 00260 memset(key, 0, <span class="keyword">sizeof</span>(*key)); 00261 <span class="comment">/*@-temptrans -assignexpose@*/</span> 00262 key-><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(&key, mc-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>, mc-><a class="code" href="structMacroContext__s.html#m2">firstFree</a>, 00265 <span class="keyword">sizeof</span>(*(mc-><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 > 0 && <a class="code" href="macro_8c.html#a1">iseol</a>(*q); q--) 00295 nb--; 00296 <span class="keywordflow">if</span> (!(nb > 0 && *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 > 0); 00309 <span class="comment">/*@-retalias@*/</span> <span class="keywordflow">return</span> (nread > 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 <= 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 >= 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>%*s(empty)"</span>), mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>, 00356 (2 * mb-><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 && !<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-><a class="code" href="structMacroBuf__s.html#m3">depth</a>); 00369 <span class="keywordflow">if</span> ((senl - s) > 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>%*s%%%.*s^"</span>, mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>, 00377 (2 * mb-><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> && (senl - (se+1)) > 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 > t)) { 00398 fprintf(stderr, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"%3d<%*s(empty)\n"</span>), mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>, (2 * mb-><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 > t && <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-><a class="code" href="structMacroBuf__s.html#m3">depth</a> > 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>)) && tenl < te) 00411 t = ++tenl; 00412 00413 <span class="comment">/* Limit expand output */</span> 00414 choplen = 61 - (2 * mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>); 00415 <span class="keywordflow">if</span> ((te - t) > choplen) { 00416 te = t + choplen; 00417 ellipsis = <span class="stringliteral">"..."</span>; 00418 } 00419 } 00420 00421 fprintf(stderr, <span class="stringliteral">"%3d<%*s"</span>, mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>, (2 * mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a> + 1), <span class="stringliteral">""</span>); 00422 <span class="keywordflow">if</span> (te > 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)) && 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)) && !(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)) && (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)) && (_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)) && !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-><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-><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-><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-><a class="code" href="structMacroBuf__s.html#m1">t</a>; 00500 size_t nb = mb-><a class="code" href="structMacroBuf__s.html#m2">nb</a>; 00501 <span class="keywordtype">int</span> rc; 00502 00503 mb-><a class="code" href="structMacroBuf__s.html#m1">t</a> = tbuf; 00504 mb-><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-><a class="code" href="structMacroBuf__s.html#m1">t</a> = t; 00507 mb-><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-><a class="code" href="structMacroBuf__s.html#m0">s</a>; 00526 <span class="keywordtype">char</span> *t = mb-><a class="code" href="structMacroBuf__s.html#m1">t</a>; 00527 size_t nb = mb-><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-><a class="code" href="structMacroBuf__s.html#m0">s</a> = u; 00536 <span class="comment">/*@=temptrans =assignexpose@*/</span> 00537 mb-><a class="code" href="structMacroBuf__s.html#m1">t</a> = tbuf; 00538 mb-><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 > mb-><a class="code" href="structMacroBuf__s.html#m2">nb</a>) 00543 strncpy(u, tbuf, (ulen - mb-><a class="code" href="structMacroBuf__s.html#m2">nb</a> + 1)); 00544 00545 mb-><a class="code" href="structMacroBuf__s.html#m0">s</a> = s; 00546 mb-><a class="code" href="structMacroBuf__s.html#m1">t</a> = t; 00547 mb-><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-><a class="code" href="structMacroBuf__s.html#m2">nb</a> > 0 && (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-><a class="code" href="structMacroBuf__s.html#m1">t</a>[-1])) { 00585 *(mb-><a class="code" href="structMacroBuf__s.html#m1">t</a>--) = <span class="charliteral">'\0'</span>; 00586 mb-><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 >= b && (c = *be) && (<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) && (<a class="code" href="rpmio_8h.html#a98">xisalpha</a>(c) || c == <span class="charliteral">'_'</span>) && (ne - n) > 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 && 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) < 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 && <a class="code" href="macro_8c.html#a32">expandU</a>(mb, b, (&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-><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) && (<a class="code" href="rpmio_8h.html#a98">xisalpha</a>(c) || c == <span class="charliteral">'_'</span>) && (ne - n) > 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-><a class="code" href="structMacroEntry__s.html#m1">name</a>, me-><a class="code" href="structMacroEntry__s.html#m1">name</a>, me-><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 && *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-><a class="code" href="structMacroEntry__s.html#m0">prev</a> = prev; 00762 <span class="comment">/*@=assignexpose@*/</span> 00763 me-><a class="code" href="structMacroEntry__s.html#m1">name</a> = (prev ? prev-><a class="code" href="structMacroEntry__s.html#m1">name</a> : <a class="code" href="rpmmalloc_8c.html#a4">xstrdup</a>(n)); 00764 me-><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-><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-><a class="code" href="structMacroEntry__s.html#m4">used</a> = 0; 00767 me-><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-><a class="code" href="structMacroEntry__s.html#m0">prev</a>) == NULL) 00788 me-><a class="code" href="structMacroEntry__s.html#m1">name</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-><a class="code" href="structMacroEntry__s.html#m1">name</a>); 00789 me-><a class="code" href="structMacroEntry__s.html#m2">opts</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-><a class="code" href="structMacroEntry__s.html#m2">opts</a>); 00790 me-><a class="code" href="structMacroEntry__s.html#m3">body</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-><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-><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-><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 < mc-><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 = &mc-><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-><a class="code" href="structMacroEntry__s.html#m5">level</a> < mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>) 00821 <span class="keywordflow">continue</span>; 00822 <span class="keywordflow">if</span> (strlen(me-><a class="code" href="structMacroEntry__s.html#m1">name</a>) == 1 && strchr(<span class="stringliteral">"#*0"</span>, *me-><a class="code" href="structMacroEntry__s.html#m1">name</a>)) { 00823 <span class="keywordflow">if</span> (*me-><a class="code" href="structMacroEntry__s.html#m1">name</a> == <span class="charliteral">'*'</span> && me-><a class="code" href="structMacroEntry__s.html#m4">used</a> > 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 && me-><a class="code" href="structMacroEntry__s.html#m4">used</a> <= 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-><a class="code" href="structMacroEntry__s.html#m1">name</a>, me-><a class="code" href="structMacroEntry__s.html#m3">body</a>, me-><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 && *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-><a class="code" href="structMacroEntry__s.html#m1">name</a>); 00866 00867 <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"0"</span>, NULL, buf, mb-><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> && 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-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"**"</span>, NULL, b, mb-><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 < 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-><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-><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-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, aname, NULL, b, mb-><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-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, aname, NULL, optarg, mb-><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-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"#"</span>, NULL, aname, mb-><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 < 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-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, aname, NULL, argv[c], mb-><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-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"*"</span>, NULL, b, mb-><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> **)&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) && <a class="code" href="macro_8c.html#a0">isblank</a>(c);) 01069 b++; 01070 <span class="keywordflow">for</span> (be = b; (c = *be) && !<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, &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) && <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) && <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-><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-><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-><a class="code" href="structMacroBuf__s.html#m3">depth</a> > <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-><a class="code" href="structMacroBuf__s.html#m3">depth</a>, <a class="code" href="macro_8c.html#a17">max_macro_depth</a>); 01151 mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>--; 01152 mb-><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 && mb-><a class="code" href="structMacroBuf__s.html#m2">nb</a> > 0 && (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-><a class="code" href="structMacroBuf__s.html#m3">depth</a> > 1) <span class="comment">/* XXX full expansion for outermost level */</span> 01175 t = mb-><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) && (<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) && <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-><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) && !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 > f */</span> 01268 fn = (fe - f); 01269 gn = (ge - g); 01270 <span class="keywordflow">if</span> ((fe - f) <= 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-><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-><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-><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 < 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-><a class="code" href="structMacroBuf__s.html#m5">expand_trace</a> = mb-><a class="code" href="structMacroBuf__s.html#m4">macro_trace</a> = (negate ? 0 : mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>); 01316 <span class="keywordflow">if</span> (mb-><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-><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-><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-><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-><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-><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 && !negate) || <span class="comment">/* Without -f, skip %{-f...} */</span> 01359 (me != NULL && 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 && g < 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 && me-><a class="code" href="structMacroEntry__s.html#m3">body</a> && *me-><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-><a class="code" href="structMacroEntry__s.html#m3">body</a>, strlen(me-><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 && !negate) || <span class="comment">/* Without -f, skip %{?f...} */</span> 01377 (me != NULL && 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 && g < 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 && me-><a class="code" href="structMacroEntry__s.html#m3">body</a> && *me-><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-><a class="code" href="structMacroEntry__s.html#m3">body</a>, strlen(me-><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 && *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 && me-><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-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"**"</span>, NULL, <span class="stringliteral">""</span>, mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>); 01417 <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"*"</span>, NULL, <span class="stringliteral">""</span>, mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>); 01418 <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"#"</span>, NULL, <span class="stringliteral">"0"</span>, mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>); 01419 <a class="code" href="macro_8c.html#a43">addMacro</a>(mb-><a class="code" href="structMacroBuf__s.html#m7">mc</a>, <span class="stringliteral">"0"</span>, NULL, me-><a class="code" href="structMacroEntry__s.html#m1">name</a>, mb-><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-><a class="code" href="structMacroEntry__s.html#m3">body</a> && *me-><a class="code" href="structMacroEntry__s.html#m3">body</a>) { 01425 <span class="comment">/*@-onlytrans@*/</span> 01426 mb-><a class="code" href="structMacroBuf__s.html#m0">s</a> = me-><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-><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-><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-><a class="code" href="structMacroBuf__s.html#m1">t</a> = <span class="charliteral">'\0'</span>; 01441 mb-><a class="code" href="structMacroBuf__s.html#m0">s</a> = s; 01442 mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a>--; 01443 <span class="keywordflow">if</span> (rc != 0 || mb-><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-><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-><a class="code" href="structMacroBuf__s.html#m0">s</a> = sbuf; 01466 <span class="comment">/*@=temptrans =assignexpose@*/</span> 01467 mb-><a class="code" href="structMacroBuf__s.html#m1">t</a> = tbuf; 01468 mb-><a class="code" href="structMacroBuf__s.html#m2">nb</a> = slen; 01469 mb-><a class="code" href="structMacroBuf__s.html#m3">depth</a> = 0; 01470 mb-><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-><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-><a class="code" href="structMacroBuf__s.html#m6">spec</a> = spec; <span class="comment">/* (future) %file expansion info */</span> 01475 mb-><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-><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-><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-><a class="code" href="structMacroContext__s.html#m2">firstFree</a> == mc-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a> != NULL) 01502 mep = mc-><a class="code" href="structMacroContext__s.html#m0">macroTable</a> + mc-><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)->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 && *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->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-><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-><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 < mc-><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 = &mc-><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-><a class="code" href="structMacroEntry__s.html#m1">name</a>, me-><a class="code" href="structMacroEntry__s.html#m2">opts</a>, me-><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 && *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> && 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 && *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> && 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-><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 < mc-><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-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a>[i] = me-><a class="code" href="structMacroEntry__s.html#m0">prev</a>) == NULL) 01654 me-><a class="code" href="structMacroEntry__s.html#m1">name</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-><a class="code" href="structMacroEntry__s.html#m1">name</a>); 01655 <span class="comment">/*@=onlytrans@*/</span> 01656 me-><a class="code" href="structMacroEntry__s.html#m2">opts</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-><a class="code" href="structMacroEntry__s.html#m2">opts</a>); 01657 me-><a class="code" href="structMacroEntry__s.html#m3">body</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(me-><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-><a class="code" href="structMacroContext__s.html#m0">macroTable</a> = <a class="code" href="poptint_8h.html#a14">_free</a>(mc-><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 < 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 < <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 >= 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>) && (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) && (magic[1] == 0113) && 01702 (magic[2] == 0003) && (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) && (magic[1] == 0213)) || <span class="comment">/* gzip */</span> 01705 ((magic[0] == 0037) && (magic[1] == 0236)) || <span class="comment">/* old gzip */</span> 01706 ((magic[0] == 0037) && (magic[1] == 0036)) || <span class="comment">/* pack */</span> 01707 ((magic[0] == 0037) && (magic[1] == 0240)) || <span class="comment">/* SCO lzh */</span> 01708 ((magic[0] == 0037) && (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 && *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, &end, 0); 01761 <span class="keywordflow">if</span> (!(end && *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 ->\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> && 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 < t && *se != <span class="charliteral">'/'</span>; se++) 01795 {}; 01796 <span class="keywordflow">if</span> (se < t && *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 > path && 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> && s[1] == <span class="charliteral">'.'</span> && (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> && 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> && s[1] == <span class="charliteral">'\0'</span>) || (t != path && 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> && t > path && t[-1] == <span class="charliteral">'/'</span> && s[1] == <span class="charliteral">'.'</span> && (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 > path) 01831 <span class="keywordflow">for</span> (--te; te > path && *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 > &path[1] && 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, &root); 01907 <span class="keywordflow">if</span> (url == NULL && ut > <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, &mdir); 01917 <span class="keywordflow">if</span> (url == NULL && ut > <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, &file); 01927 <span class="keywordflow">if</span> (url == NULL && ut > <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 && nurl > 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 >= 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 < 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->%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->%s\n <-\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>