Imported Upstream version 3.1.0
[debian/amanda] / common-src / columnar.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-2000 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author: James da Silva, Systems Design and Analysis Group
24  *                         Computer Science Department
25  *                         University of Maryland at College Park
26  */
27 /*
28  * Originally living in conffile.c, this stuff supports columnar output in amreport.
29  */
30
31
32 #include "amanda.h"
33 #include "columnar.h"
34
35 ColumnInfo ColumnData[] = {
36     { "HostName",   0, 12, 12, 0, "%-*.*s", "HOSTNAME" },
37     { "Disk",       1, 11, 11, 0, "%-*.*s", "DISK" },
38     { "Level",      1, 1,  1,  0, "%*.*d",  "L" },
39     { "OrigKB",     1, 7,  0,  1, "%*.*lf", "ORIG-KB" },
40     { "OutKB",      1, 7,  0,  1, "%*.*lf", "OUT-KB" },
41     { "Compress",   1, 6,  1,  1, "%*.*lf", "COMP%" },
42     { "DumpTime",   1, 7,  7,  1, "%*.*s",  "MMM:SS" },
43     { "DumpRate",   1, 6,  1,  1, "%*.*lf", "KB/s" },
44     { "TapeTime",   1, 6,  6,  1, "%*.*s",  "MMM:SS" },
45     { "TapeRate",   1, 6,  1,  1, "%*.*lf", "KB/s" },
46     { NULL,         0, 0,  0,  0, NULL,     NULL }
47 };
48
49
50 int
51 ColumnDataCount(void )
52 {
53     return (int)(SIZEOF(ColumnData) / SIZEOF(ColumnData[0]));
54 }
55
56 /* conversion from string to table index
57  */
58 int
59 StringToColumn(
60     char *s)
61 {
62     int cn;
63
64     for (cn=0; ColumnData[cn].Name != NULL; cn++) {
65         if (strcasecmp(s, ColumnData[cn].Name) == 0) {
66             break;
67         }
68     }
69     return cn;
70 }
71
72 char
73 LastChar(
74     char *s)
75 {
76     return s[strlen(s)-1];
77 }
78
79 int
80 SetColumnDataFromString(
81     ColumnInfo* ci,
82     char *s,
83     char **errstr)
84 {
85     ci = ci;
86
87     /* Convert from a Columnspec string to our internal format
88      * of columspec. The purpose is to provide this string
89      * as configuration paramter in the amanda.conf file or
90      * (maybe) as environment variable.
91      * 
92      * This text should go as comment into the sample amanda.conf
93      *
94      * The format for such a ColumnSpec string s is a ',' seperated
95      * list of triples. Each triple consists of
96      *   -the name of the column (as in ColumnData.Name)
97      *   -prefix before the column
98      *   -the width of the column
99      *       if set to -1 it will be recalculated
100      *       to the maximum length of a line to print.
101      *   -the precision (number of digit after the dot)
102      * Example:
103      *  "Disk=1:17,HostName=1:10,OutKB=1:7"
104      * or
105      *  "Disk=1:-1,HostName=1:10,OutKB=1:7"
106      *  
107      * You need only specify those colums that should be changed from
108      * the default. If nothing is specified in the configfile, the
109      * above compiled in values will be in effect, resulting in an
110      * output as it was all the time.
111      *                                                  ElB, 1999-02-24.
112      */
113
114     while (s && *s) {
115         int Space, Width, Precision;
116         int cn;
117         char *eon= strchr(s, '=');
118
119         if (eon == NULL) {
120             *errstr = stralloc2(_("invalid columnspec: "), s);
121             return -1;
122         }
123         *eon= '\0';
124         cn=StringToColumn(s);
125         if (ColumnData[cn].Name == NULL) {
126             *errstr = stralloc2(_("invalid column name: "), s);
127             return -1;
128         }
129         if (sscanf(eon+1, "%d:%d:%d", &Space, &Width, &Precision) == 3) {
130             ColumnData[cn].PrefixSpace = Space;
131             ColumnData[cn].Width = Width;
132             ColumnData[cn].Precision = Precision;
133             if (Width > 0)
134                 ColumnData[cn].MaxWidth = 0;
135         } else if (sscanf(eon+1, ":%d:%d", &Width, &Precision) == 2) {
136             ColumnData[cn].Width = Width;
137             ColumnData[cn].Precision = Precision;
138             if (Width > 0)
139                 ColumnData[cn].MaxWidth = 0;
140         } else if (sscanf(eon+1, "%d::%d", &Space, &Precision) == 2) {
141             ColumnData[cn].PrefixSpace = Space;
142             ColumnData[cn].Precision = Precision;
143         } else if (sscanf(eon+1, "%d:%d", &Space, &Width) == 2) {
144             ColumnData[cn].PrefixSpace = Space;
145             ColumnData[cn].Width = Width;
146         } else if (sscanf(eon+1, "::%d", &Precision) == 1) {
147             ColumnData[cn].Precision = Precision;
148         } else if (sscanf(eon+1, ":%d", &Width) == 1) {
149             ColumnData[cn].Width = Width;
150             if (Width > 0)
151                 ColumnData[cn].MaxWidth = 0;
152         } else if (sscanf(eon+1, "%d", &Space) == 1) {
153             ColumnData[cn].PrefixSpace = Space;
154         } else {
155             *errstr = stralloc2(_("invalid format: "), eon + 1);
156             return -1;
157         }
158
159         if (ColumnData[cn].Width < 0) {
160             ColumnData[cn].MaxWidth = 1;
161             ColumnData[cn].Width = abs(ColumnData[cn].MaxWidth);
162         } else {
163             if (LastChar(ColumnData[cn].Format) == 's') {
164                 if (ColumnData[cn].Width > ColumnData[cn].Precision)
165                     ColumnData[cn].Precision = ColumnData[cn].Width;
166             } else if (ColumnData[cn].Width < ColumnData[cn].Precision) {
167                 ColumnData[cn].Precision = ColumnData[cn].Width;
168             }
169         }
170         s= strchr(eon+1, ',');
171         if (s != NULL)
172             s++;
173     }
174     return 0;
175 }
176