rpm 5.3.12
build/parseDescription.c
Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include <rpmio.h>
00009 #include <rpmiotypes.h>
00010 #include <rpmlog.h>
00011 #include "rpmbuild.h"
00012 #include "debug.h"
00013 
00014 /*@-exportheadervar@*/
00015 /*@unchecked@*/
00016 extern int noLang;
00017 /*@=exportheadervar@*/
00018 
00019 /* These have to be global scope to make up for *stupid* compilers */
00020 /*@unchecked@*/
00021     /*@observer@*/ /*@null@*/ static const char *name = NULL;
00022 /*@unchecked@*/
00023     /*@observer@*/ /*@null@*/ static const char *lang = NULL;
00024 
00025 /*@unchecked@*/
00026     static struct poptOption optionsTable[] = {
00027         { NULL, 'n', POPT_ARG_STRING, &name, 0, NULL, NULL},
00028         { NULL, 'l', POPT_ARG_STRING, &lang, 0, NULL, NULL},
00029         { 0, 0, 0, 0, 0,        NULL, NULL}
00030     };
00031 
00032 int parseDescription(Spec spec)
00033         /*@globals name, lang @*/
00034         /*@modifies name, lang @*/
00035 {
00036     rpmParseState nextPart = (rpmParseState) RPMRC_FAIL; /* assume error */
00037     rpmiob iob = NULL;
00038     int flag = PART_SUBNAME;
00039     Package pkg;
00040     int rc, argc;
00041     int arg;
00042     const char **argv = NULL;
00043     poptContext optCon = NULL;
00044     spectag t = NULL;
00045 
00046     {   char * se = strchr(spec->line, '#');
00047         if (se) {
00048             *se = '\0';
00049             while (--se >= spec->line && strchr(" \t\n\r", *se) != NULL)
00050                 *se = '\0';
00051         }
00052     }
00053 
00054     if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
00055         rpmlog(RPMLOG_ERR, _("line %d: Error parsing %%description: %s\n"),
00056                  spec->lineNum, poptStrerror(rc));
00057         goto exit;
00058     }
00059 
00060     name = NULL;
00061     lang = RPMBUILD_DEFAULT_LANG;
00062     optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
00063     while ((arg = poptGetNextOpt(optCon)) > 0)
00064         {;}
00065     if (name != NULL)
00066         flag = PART_NAME;
00067 
00068     if (arg < -1) {
00069         rpmlog(RPMLOG_ERR, _("line %d: Bad option %s: %s\n"),
00070                  spec->lineNum,
00071                  poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
00072                  spec->line);
00073         goto exit;
00074     }
00075 
00076     if (poptPeekArg(optCon)) {
00077         if (name == NULL)
00078             name = poptGetArg(optCon);
00079         if (poptPeekArg(optCon)) {
00080             rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"),
00081                      spec->lineNum, spec->line);
00082             goto exit;
00083         }
00084     }
00085 
00086     if (lookupPackage(spec, name, flag, &pkg) != RPMRC_OK) {
00087         rpmlog(RPMLOG_ERR, _("line %d: Package does not exist: %s\n"),
00088                  spec->lineNum, spec->line);
00089         goto exit;
00090     }
00091 
00092     /* Lose the inheirited %description (if present). */
00093     if (spec->packages->header != pkg->header) {
00094         HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00095         int xx;
00096         he->tag = RPMTAG_DESCRIPTION;
00097         xx = headerGet(pkg->header, he, 0);
00098         he->p.ptr = _free(he->p.ptr);
00099         if (xx && he->t == RPM_STRING_TYPE)
00100             xx = headerDel(pkg->header, he, 0);
00101     }
00102     
00103     t = stashSt(spec, pkg->header, RPMTAG_DESCRIPTION, lang);
00104     
00105     iob = rpmiobNew(0);
00106 
00107     if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) {
00108         nextPart = PART_NONE;
00109         goto exit;
00110     }
00111     if (rc < 0) {
00112             nextPart = (rpmParseState) RPMRC_FAIL;
00113             goto exit;
00114         }
00115 
00116         while ((nextPart = isPart(spec)) == PART_NONE) {
00117             iob = rpmiobAppend(iob, spec->line, 1);
00118             if (t) t->t_nlines++;
00119         if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) {
00120                 nextPart = PART_NONE;
00121                 break;
00122             }
00123             if (rc) {
00124                 nextPart = (rpmParseState) RPMRC_FAIL;
00125                 goto exit;
00126             }
00127         }
00128     
00129     iob = rpmiobRTrim(iob);
00130     if (!(noLang && strcmp(lang, RPMBUILD_DEFAULT_LANG))) {
00131         const char * s = rpmiobStr(iob);
00132         (void) headerAddI18NString(pkg->header, RPMTAG_DESCRIPTION, s, lang);
00133     }
00134     
00135 exit:
00136     iob = rpmiobFree(iob);
00137     argv = _free(argv);
00138     optCon = poptFreeContext(optCon);
00139     return nextPart;
00140 }