Sfoglia il codice sorgente

add support for field width specification

Wichert Akkerman 25 anni fa
parent
commit
62cfc2cbf4
2 ha cambiato i file con 65 aggiunte e 13 eliminazioni
  1. 5 0
      ChangeLog
  2. 60 13
      main/showpkg.c

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+Fri Jul 27 03:43:52 CEST 2001 Wichert Akkerman <wakkerma@debian.org>
+
+  * main/query.c: remove -D from usage, we don't support it
+  * main/showpkg.c: add support for field width specification
+
 Thu Jul 26 14:27:23 CEST 2001 Wichert Akkerman <wakkerma@debian.org>
 
   * scripts/Makefile.in, doc/fr/Makefile.in, doc/ja/Makefile.in,

+ 60 - 13
main/showpkg.c

@@ -35,6 +35,7 @@ typedef enum { invalid, string, field } itemtype_t;
 struct lstitem {
 	itemtype_t type;
 	size_t width;
+	int pad;
 	char* data;
 	struct lstitem* next;
 };
@@ -48,22 +49,48 @@ static struct lstitem* alloclstitem() {
 	buf->next=NULL;
 	buf->data=NULL;
 	buf->width=0;
+	buf->pad=0;
 
 	return buf;
 }
 
-static void parsefield(struct lstitem* cur, const char* fmt, const char* fmtend) {
+
+static int parsefield(struct lstitem* cur, const char* fmt, const char* fmtend) {
 	int len;
+	const char* ws;
 
 	len=fmtend-fmt+1;
 
+	ws=(const char*)memchr(fmt, ';', len);
+	if (ws) {
+		char* endptr;
+		long w;
+
+		w=strtol(ws+1,&endptr,0);
+		if (endptr[0]!='}') {
+			fprintf(stderr, _("invalid character `%c' in field width\n"), *endptr);
+			return 0;
+		}
+
+		if (w<0) {
+			cur->pad=1;
+			cur->width=(size_t)-w;
+		} else
+			cur->width=(size_t)w;
+
+		len=ws-fmt;
+	}
+
 	cur->type=field;
 	cur->data=(char*)malloc(len+1);
 	memcpy(cur->data, fmt, len);
 	cur->data[len]='\0';
+
+	return 1;
 }
 
-static void parsestring(struct lstitem* cur, const char* fmt, const char* fmtend) {
+
+static int parsestring(struct lstitem* cur, const char* fmt, const char* fmtend) {
 	int len;
 	char* write;
 
@@ -95,6 +122,8 @@ static void parsestring(struct lstitem* cur, const char* fmt, const char* fmtend
 		fmt++;
 	}
 	*write='\0';
+
+	return 1;
 }
 
 
@@ -109,6 +138,7 @@ void freeformat(struct lstitem* head) {
 	}
 }
 
+
 struct lstitem* parseformat(const char* fmt) {
 	struct lstitem* head;
 	struct lstitem* cur;
@@ -123,14 +153,17 @@ struct lstitem* parseformat(const char* fmt) {
 			head=cur=alloclstitem();
 
 		if (fmt[0]=='$' && fmt[1]=='{') {
-			fmtend=strchr(fmt, '}');  // TODO: check for not-found
+			fmtend=strchr(fmt, '}');
 			if (!fmtend) {
 				fprintf(stderr, _("Closing brace missing in format\n"));
 				freeformat(head);
 				return NULL;
 			}
 			cur->type=field;
-			parsefield(cur, fmt+2, fmtend-1);
+			if (!parsefield(cur, fmt+2, fmtend-1)) {
+				freeformat(head);
+				return NULL;
+			}
 			fmt=fmtend+1;
 		} else {
 			fmtend=fmt;
@@ -142,7 +175,10 @@ struct lstitem* parseformat(const char* fmt) {
 			if (!fmtend)
 				fmtend=fmt+strlen(fmt);
 
-			parsestring(cur, fmt, fmtend-1);
+			if (!parsestring(cur, fmt, fmtend-1)) {
+				freeformat(head);
+				return NULL;
+			}
 			fmt=fmtend;
 		}
 	}
@@ -163,7 +199,7 @@ static void dumpchain(struct lstitem* head) {
 
 
 void show1package(const struct lstitem* head, struct pkginfo *pkg) {
-	struct varbuf vb, fb;
+	struct varbuf vb, fb, wb;
 
 	/* Make sure we have package info available, even if it's all empty. */
 	if (!pkg->installed.valid)
@@ -171,14 +207,22 @@ void show1package(const struct lstitem* head, struct pkginfo *pkg) {
 
 	varbufinit(&vb);
 	varbufinit(&fb);
+	varbufinit(&wb);
 
 	while (head) {
 		int ok;
+		char fmt[16];
 
 		ok=0;
 
+		if (head->width>0)
+			snprintf(fmt,16,"%%%s%ds",
+				((head->pad) ? "-" : ""), head->width);
+		else
+			strcpy(fmt, "%s");
+
 		if (head->type==string) {
-			varbufprintf(&fb, "%s", head->data);
+			varbufprintf(&fb, fmt, head->data);
 			ok=1;
 		} else if (head->type==field) {
 			const struct fieldinfo* fip;
@@ -188,18 +232,20 @@ void show1package(const struct lstitem* head, struct pkginfo *pkg) {
 					size_t len;
 					char* i;
 
-					fip->wcall(&fb,pkg,&pkg->installed,fip);
-					if (!fb.used)
+					fip->wcall(&wb,pkg,&pkg->installed,fip);
+					if (!wb.used)
 						break;
 					/* Bugger, wcall adds the fieldname and a trailing newline we
 					 * do not need. We should probably improve wcall to only do that
 					 * optionally, but this will do for now (ie this is a TODO)
 					 */
-					fb.buf[fb.used-1]='\0';
-					i=strchr(fb.buf, ':')+2;
+					wb.buf[wb.used-1]='\0';
+					i=strchr(wb.buf, ':')+2;
 					len=strlen(i)+1;
-					memmove(fb.buf, i, len);
+					memmove(wb.buf, i, len);
 
+					varbufprintf(&fb, fmt, wb.buf);
+					varbufreset(&wb);
 					ok=1;
 					break;
 				}
@@ -209,7 +255,7 @@ void show1package(const struct lstitem* head, struct pkginfo *pkg) {
 
 				for (afp=pkg->installed.arbs; afp; afp=afp->next)
 					if (strcasecmp(head->data, afp->name)==0) {
-						varbufprintf(&fb, "%s", afp->value);
+						varbufprintf(&fb, fmt, afp->value);
 						ok=1;
 						break;
 					}
@@ -232,6 +278,7 @@ void show1package(const struct lstitem* head, struct pkginfo *pkg) {
 		fputs(vb.buf,stdout);
 	}
 
+	varbuffree(&wb);
 	varbuffree(&fb);
 	varbuffree(&vb);
 }