rpm  5.4.4
ruby/trb.c
Go to the documentation of this file.
00001 #include "system.h"
00002 
00003 #include <rpmio.h>
00004 #include <argv.h>
00005 
00006 #define _RPMRUBY_INTERNAL
00007 #include <rpmruby.h>
00008 
00009 #include "rpm-rb.h"
00010 
00011 #include "rpmds-rb.h"
00012 #include "rpmfi-rb.h"
00013 #include "rpmhdr-rb.h"
00014 #include "rpmmc-rb.h"
00015 #include "rpmmi-rb.h"
00016 #include "rpmps-rb.h"
00017 #include "rpmte-rb.h"
00018 #include "rpmts-rb.h"
00019 
00020 #ifdef  NOTYET
00021 #include "syck-rb.h"
00022 #include "uuid-rb.h"
00023 #endif
00024 
00025 #include <rpmcli.h>
00026 
00027 #include "debug.h"
00028 
00029 /*@unchecked@*/
00030 static int _debug = 0;
00031 
00032 /*@unchecked@*/
00033 static int _loglvl = 0;
00034 
00035 /*@unchecked@*/
00036 static int _test = 1;
00037 
00038 typedef struct rpmrbClassTable_s {
00039 /*@observer@*/
00040     const char *name;
00041     void (*init) (void);
00042     int ix;
00043 } * rpmrbClassTable;
00044 
00045 /*@unchecked@*/ /*@observer@*/
00046 static struct rpmrbClassTable_s classTable[] = {
00047     { "Ps",                Init_rpmps,    9 },
00048     { "Mc",                Init_rpmmc,    8 },
00049     { "Te",                Init_rpmte,    7 },
00050     { "Fi",                Init_rpmfi,    6 },
00051     { "Ds",                Init_rpmds,    5 },
00052     { "Hdr",               Init_rpmhdr,   4 },
00053     { "Mi",                Init_rpmmi,    3 },
00054     { "Ts",                Init_rpmts,    2 },
00055     { "Rpm",               Init_rpm,      1 },
00056 };
00057 
00058 /*@unchecked@*/
00059 static size_t nclassTable = sizeof(classTable) / sizeof(classTable[0]);
00060 
00061 /*@unchecked@*/
00062 static const char tscripts[] = "./tscripts/";
00063 
00064 /*@unchecked@*/
00065 static const char * _acknack = "\
00066 def ack(cmd, expected)\n\
00067   begin\n\
00068     actual = eval(cmd)\n\
00069   rescue\n\
00070     print(\"NACK:  ack(\"+cmd.to_s+\")\tcaught '\"+\"#{$!}\"+\"'\n\")\n\
00071     return\n\
00072   end\n\
00073   if (actual != expected && expected != nil)\n\
00074     print(\"NACK:  ack(\"+cmd.to_s+\")\tgot '\"+actual.to_s+\"' not '\"+expected.to_s+\"'\n\")\n\
00075   elsif ($loglvl)\n\
00076     print(\"       ack(\"+cmd.to_s+\")\tgot '\"+actual.to_s+\"'\n\")\n\
00077   end\n\
00078 end\n\
00079 ";
00080 
00081 static rpmRC
00082 rpmrbLoadFile(rpmruby rb, const char * pre, const char * fn)
00083 {
00084     const char * result = NULL;
00085     char * str;
00086     rpmRC ret;
00087 
00088     if (pre == NULL)
00089         pre = "";
00090     str = rpmExpand(pre, "load(\"", fn, "\");", NULL);
00091 if (_debug)
00092 fprintf(stderr, "\trunning:%s%s\n", (*pre ? "\n" : " "), str);
00093     result = NULL;
00094     ret = rpmrubyRun(NULL, str, &result);
00095     if (result != NULL && *result != '\0')
00096         fprintf(stdout, "%s\n", result);
00097     str = _free(str);
00098     return ret;
00099 }
00100 
00101 static void
00102 rpmrbLoadClasses(void)
00103 {
00104     const char * pre = NULL;
00105     int * order = NULL;
00106     size_t norder = 64;
00107     rpmrbClassTable tbl;
00108     rpmruby rb;
00109     const char * result;
00110     int ix;
00111     size_t i;
00112 
00113     i = norder * sizeof(*order);
00114     order = memset(alloca(i), 0, i);
00115 
00116     /* Inject _debug and _loglvl into the interpreter context. */
00117     {   char dstr[32];
00118         char lstr[32];
00119         sprintf(dstr, "%d", _debug);
00120         sprintf(lstr, "%d", _loglvl);
00121         pre = rpmExpand("$debug = ", dstr, ";\n"
00122                         "$loglvl = ", lstr, ";\n",
00123                         _acknack, NULL);
00124     }
00125 
00126     /* Load requested classes and initialize the test order. */
00127     /* XXX FIXME: resultp != NULL to actually execute?!? */
00128     (void) rpmrubyRun(NULL, "puts \"loading RPM classes.\";", &result);
00129     rb = _rpmrubyI;
00130     for (i = 0, tbl = classTable; i < nclassTable; i++, tbl++) {
00131         if (tbl->ix <= 0)
00132             continue;
00133         order[tbl->ix & (norder - 1)] = i + 1;
00134         if (tbl->init != NULL)
00135             (void) (*tbl->init) ();
00136     }
00137 
00138     /* Test requested classes in order. */
00139     for (i = 0; i < norder; i++) {
00140         const char * fn;
00141         struct stat sb;
00142 
00143         if (order[i] <= 0)
00144             continue;
00145         ix = order[i] - 1;
00146         tbl = &classTable[ix];
00147         fn = rpmGetPath(tscripts, "/", tbl->name, ".rb", NULL);
00148         if (Stat(fn, &sb) == 0) {
00149             (void) rpmrbLoadFile(NULL, pre, fn);
00150             pre = _free(pre);
00151         }
00152         fn = _free(fn);
00153     }
00154 
00155     pre = _free(pre);
00156     return;
00157 }
00158 
00159 static struct poptOption optionsTable[] = {
00160  { "debug", 'd', POPT_ARG_VAL,  &_debug, -1,            NULL, NULL },
00161  { "test", 't', POPT_ARG_VAL,   &_test, -1,             NULL, NULL },
00162 
00163  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
00164         N_("Common options for all rpm executables:"), NULL },
00165 
00166   POPT_AUTOHELP
00167   POPT_TABLEEND
00168 };
00169 
00170 int
00171 main(int argc, char *argv[])
00172 {
00173     poptContext optCon = rpmcliInit(argc, argv, optionsTable);
00174     ARGV_t av = poptGetArgs(optCon);
00175     int ac = argvCount(av);
00176     const char * fn;
00177     int rc = 1;         /* assume failure */
00178 
00179     if (!_test && ac < 1) {
00180         poptPrintUsage(optCon, stderr, 0);
00181         goto exit;
00182     }
00183 
00184 _rpmts_debug = 0;
00185 
00186 _rpmruby_debug = 0;
00187     if (_debug && !_loglvl) _loglvl = 1;
00188     rpmrbLoadClasses();
00189 _rpmruby_debug = 1;
00190 
00191     if (av != NULL)
00192     while ((fn = *av++) != NULL) {
00193         rpmRC ret = rpmrbLoadFile(NULL, NULL, fn);
00194         if (ret != RPMRC_OK)
00195             goto exit;
00196     }
00197 
00198     rc = 0;
00199 
00200 exit:
00201 _rpmruby_debug = 0;
00202     optCon = rpmcliFini(optCon);
00203 
00204     return rc;
00205 }