Main Page   Modules   Compound List   File List   Compound Members   File Members   Related Pages  

build/parseChangelog.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include "rpmbuild.h"
00009 #include "debug.h"
00010 
00011 void addChangelogEntry(Header h, time_t time, const char *name, const char *text)
00012 {
00013     int_32 mytime = time;       /* XXX convert to header representation */
00014     if (headerIsEntry(h, RPMTAG_CHANGELOGTIME)) {
00015         headerAppendEntry(h, RPMTAG_CHANGELOGTIME, RPM_INT32_TYPE,
00016                           &mytime, 1);
00017         headerAppendEntry(h, RPMTAG_CHANGELOGNAME, RPM_STRING_ARRAY_TYPE,
00018                           &name, 1);
00019         headerAppendEntry(h, RPMTAG_CHANGELOGTEXT, RPM_STRING_ARRAY_TYPE,
00020                          &text, 1);
00021     } else {
00022         headerAddEntry(h, RPMTAG_CHANGELOGTIME, RPM_INT32_TYPE,
00023                        &mytime, 1);
00024         headerAddEntry(h, RPMTAG_CHANGELOGNAME, RPM_STRING_ARRAY_TYPE,
00025                        &name, 1);
00026         headerAddEntry(h, RPMTAG_CHANGELOGTEXT, RPM_STRING_ARRAY_TYPE,
00027                        &text, 1);
00028     }
00029 }
00030 
00037 static int dateToTimet(const char * datestr, /*@out@*/ time_t * secs)
00038 {
00039     struct tm time;
00040     char *p, *pe, *q, ** idx;
00041     char * date = strcpy(alloca(strlen(datestr) + 1), datestr);
00042     static char * days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 
00043                                 NULL };
00044     static char * months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00045                              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
00046     static char lengths[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
00047     
00048     memset(&time, 0, sizeof(time));
00049 
00050     pe = date;
00051 
00052     /* day of week */
00053     p = pe; SKIPSPACE(p);
00054     if (*p == '\0') return -1;
00055     pe = p; SKIPNONSPACE(pe); if (*pe) *pe++ = '\0';
00056     for (idx = days; *idx && strcmp(*idx, p); idx++)
00057         ;
00058     if (*idx == NULL) return -1;
00059 
00060     /* month */
00061     p = pe; SKIPSPACE(p);
00062     if (*p == '\0') return -1;
00063     pe = p; SKIPNONSPACE(pe); if (*pe) *pe++ = '\0';
00064     for (idx = months; *idx && strcmp(*idx, p); idx++)
00065         ;
00066     if (*idx == NULL) return -1;
00067     time.tm_mon = idx - months;
00068 
00069     /* day */
00070     p = pe; SKIPSPACE(p);
00071     if (*p == '\0') return -1;
00072     pe = p; SKIPNONSPACE(pe); if (*pe) *pe++ = '\0';
00073 
00074     /* make this noon so the day is always right (as we make this UTC) */
00075     time.tm_hour = 12;
00076 
00077     time.tm_mday = strtol(p, &q, 10);
00078     if (!(q && *q == '\0')) return -1;
00079     if (time.tm_mday < 0 || time.tm_mday > lengths[time.tm_mon]) return -1;
00080 
00081     /* year */
00082     p = pe; SKIPSPACE(p);
00083     if (*p == '\0') return -1;
00084     pe = p; SKIPNONSPACE(pe); if (*pe) *pe++ = '\0';
00085     time.tm_year = strtol(p, &q, 10);
00086     if (!(q && *q == '\0')) return -1;
00087     if (time.tm_year < 1997 || time.tm_year >= 3000) return -1;
00088     time.tm_year -= 1900;
00089 
00090     *secs = mktime(&time);
00091     if (*secs == -1) return -1;
00092 
00093     /* adjust to GMT */
00094     *secs += timezone;
00095 
00096     return 0;
00097 }
00098 
00105 static int addChangelog(Header h, StringBuf sb)
00106 {
00107     char *s;
00108     int i;
00109     time_t time;
00110     time_t lastTime = 0;
00111     char *date, *name, *text, *next;
00112 
00113     s = getStringBuf(sb);
00114 
00115     /* skip space */
00116     SKIPSPACE(s);
00117 
00118     while (*s) {
00119         if (*s != '*') {
00120             rpmError(RPMERR_BADSPEC,
00121                         _("%%changelog entries must start with *\n"));
00122             return RPMERR_BADSPEC;
00123         }
00124 
00125         /* find end of line */
00126         date = s;
00127         while(*s && *s != '\n') s++;
00128         if (! *s) {
00129             rpmError(RPMERR_BADSPEC, _("incomplete %%changelog entry\n"));
00130             return RPMERR_BADSPEC;
00131         }
00132         *s = '\0';
00133         text = s + 1;
00134         
00135         /* 4 fields of date */
00136         date++;
00137         s = date;
00138         for (i = 0; i < 4; i++) {
00139             SKIPSPACE(s);
00140             SKIPNONSPACE(s);
00141         }
00142         SKIPSPACE(date);
00143         if (dateToTimet(date, &time)) {
00144             rpmError(RPMERR_BADSPEC, _("bad date in %%changelog: %s\n"), date);
00145             return RPMERR_BADSPEC;
00146         }
00147         if (lastTime && lastTime < time) {
00148             rpmError(RPMERR_BADSPEC,
00149                      _("%%changelog not in decending chronological order\n"));
00150             return RPMERR_BADSPEC;
00151         }
00152         lastTime = time;
00153 
00154         /* skip space to the name */
00155         SKIPSPACE(s);
00156         if (! *s) {
00157             rpmError(RPMERR_BADSPEC, _("missing name in %%changelog\n"));
00158             return RPMERR_BADSPEC;
00159         }
00160 
00161         /* name */
00162         name = s;
00163         while (*s) s++;
00164         while (s > name && isspace(*s)) {
00165             *s-- = '\0';
00166         }
00167         if (s == name) {
00168             rpmError(RPMERR_BADSPEC, _("missing name in %%changelog\n"));
00169             return RPMERR_BADSPEC;
00170         }
00171 
00172         /* text */
00173         SKIPSPACE(text);
00174         if (! *text) {
00175             rpmError(RPMERR_BADSPEC, _("no description in %%changelog\n"));
00176             return RPMERR_BADSPEC;
00177         }
00178             
00179         /* find the next leading '*' (or eos) */
00180         s = text;
00181         do {
00182            s++;
00183         } while (*s && (*(s-1) != '\n' || *s != '*'));
00184         next = s;
00185         s--;
00186 
00187         /* backup to end of description */
00188         while ((s > text) && isspace(*s)) {
00189             *s-- = '\0';
00190         }
00191         
00192         addChangelogEntry(h, time, name, text);
00193         s = next;
00194     }
00195 
00196     return 0;
00197 }
00198 
00199 int parseChangelog(Spec spec)
00200 {
00201     int nextPart, res, rc;
00202     StringBuf sb;
00203 
00204     sb = newStringBuf();
00205     
00206     /* There are no options to %changelog */
00207     if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
00208         freeStringBuf(sb);
00209         return PART_NONE;
00210     }
00211     if (rc)
00212         return rc;
00213     
00214     while (! (nextPart = isPart(spec->line))) {
00215         appendStringBuf(sb, spec->line);
00216         if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
00217             nextPart = PART_NONE;
00218             break;
00219         }
00220         if (rc)
00221             return rc;
00222     }
00223 
00224     res = addChangelog(spec->packages->header, sb);
00225     freeStringBuf(sb);
00226 
00227     return (res) ? res : nextPart;
00228 }

Generated at Mon May 21 08:53:38 2001 for rpm by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001