1 /* ---------------------------------------------------------------------- *
2  * screen.c
3  * This file is part of lincity.
4  * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
5  * Portions copyright (c) Corey Keasling, 2001.
6  * ---------------------------------------------------------------------- */
7 
8 #include "lcconfig.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include "lcstring.h"
12 #include "cliglobs.h"
13 #include "lcintl.h"
14 
15 char*
current_month(int current_time)16 current_month (int current_time)
17 {
18     return _(months[(current_time % NUMOF_DAYS_IN_YEAR) / NUMOF_DAYS_IN_MONTH]);
19 }
20 
21 int
current_year(int current_time)22 current_year (int current_time)
23 {
24     return current_time / NUMOF_DAYS_IN_YEAR;
25 }
26 
27 void
format_number5(char * str,int num)28 format_number5 (char* str, int num)
29 {
30     int num_sign = num >= 0 ? 1 : -1;
31     if (num_sign == 1) {
32 	if (num < 99999) {
33 	    sprintf (str, "%5d", num);
34 	} else if (num < 9999999) {
35 	    sprintf (str, "%4dK", num / 1000);
36 	} else {
37 	    sprintf (str, "%4dM", num / 1000000);
38 	}
39     } else {
40 	int num_absval = num_sign * num;
41 	if (num_absval < 9999) {
42 	    sprintf (str, "%5d", num);
43 	} else if (num_absval < 999999) {
44 	    sprintf (str, "%4dK", num_sign * (num_absval / 1000));
45 	} else {
46 	    sprintf (str, "%4dM", num_sign * (num_absval / 1000000));
47 	}
48     }
49 }
50 
51 void
num_to_ansi(char * s,size_t size,long num)52 num_to_ansi(char * s, size_t size, long num)
53 {
54   int triplets = 0;
55   float numf = (float)num;
56 
57   while (numf > 1000 || numf < -1000) {
58     numf /= 1000;
59     triplets++;
60   }
61 
62   switch(triplets)
63     {
64     case 0: triplets = ' '; break;
65     case 1: triplets = 'k'; break; // kila
66     case 2: triplets = 'm'; break; // mega
67     case 3: triplets = 'g'; break; // giga
68     case 4: triplets = 't'; break; // tera
69     case 5: triplets = 'p'; break; // peta
70     default: triplets = '?'; break;
71     }
72 
73   if (size == 4) { /* to make up for format_pos_number4.  Eeewwwwwww. */
74       if (numf < 10) {
75 	  snprintf(s, size + 1, "%1.1f%c", numf, triplets);
76       } else {
77 	  snprintf(s,size + 1, "%3.0f%c", numf, triplets);
78       }
79   } else {
80       if (triplets == ' ') {
81 	  snprintf(s, size, "%3.1f", numf);
82       } else {
83 	  snprintf(s, size, "%3.1f%c", numf, triplets);
84       }
85   }
86 }
87 
88 void
num_to_ansi_unit(char * s,size_t size,long num,char unit)89 num_to_ansi_unit(char * s, size_t size, long num, char unit)
90 {
91   int triplets = 0;
92   float numf = (float)num;
93 
94   while (numf > 1000) {
95     numf /= 1000;
96     triplets++;
97   }
98 
99   switch(triplets)
100     {
101     case 0: triplets = ' '; break;
102     case 1: triplets = 'k'; break; // kila
103     case 2: triplets = 'm'; break; // mega
104     case 3: triplets = 'g'; break; // giga
105     case 4: triplets = 't'; break; // tera
106     case 5: triplets = 'p'; break; // peta
107     default: triplets = '?'; break;
108     }
109 
110   if (size == 4)  /* to make up for format_pos_number4 */
111     if (numf < 10)
112       snprintf(s, size, "%4.1f%c%c", numf, triplets, unit);
113     else
114       snprintf(s,size, "%4.0f%c%c", numf, triplets, unit);
115   else
116     snprintf(s, size, "%5.1f%c%c", numf, triplets, unit);
117 }
118 
119 /* commify: take a number and convert it to a string grouped into triplets
120    with commas; returns number of characters written, excluding trailing zero
121 */
122 int
commify(char * str,size_t size,int argnum)123 commify (char *str, size_t size, int argnum)
124 {
125     size_t count = 0;
126     int i = 0;
127     int triad = 1;
128     int num = argnum;
129     int kludge = 1;
130 
131     if (num < 0)
132 	count += snprintf(str, size, "-");
133 
134     num = abs(argnum);
135 
136     for (; num >= 1000; num /= 1000, triad++, kludge *= 1000);
137 
138     num = abs(argnum);
139 
140     for (; triad > 0; i++, triad--) {
141 
142 	if (i == 0)
143 	    if (triad == 1)
144 		count += snprintf(str + count, size - count, "%d", num);
145 	    else
146 		count += snprintf(str + count, size - count, "%d,",
147 				  num ? num / kludge : num);
148 	else if (triad == 1)
149 	    count += snprintf(str + count, size - count, "%03d",
150 			      num ? num / kludge : num);
151 	else
152 	    count += snprintf(str + count, size - count, "%03d,",
153 			      num ? num / kludge : num);
154 
155 	if (num) /* don't divide by zero */
156 	    num %= kludge;
157 
158 	kludge /= 1000;
159     }
160 
161     return count;
162 }
163 
164 /* GCS - make sure that the string has length at least size-1 */
165 void
pad_with_blanks(char * str,int size)166 pad_with_blanks (char* str, int size)
167 {
168   while (*str) {
169     size--;
170     str++;
171   }
172   while (size-- > 1) {
173     *str++ = ' ';
174   }
175   *str = '\0';
176 }
177 
178 void
format_pos_number4(char * str,int num)179 format_pos_number4 (char* str, int num)
180 {
181   num_to_ansi(str, 4, num);
182 }
183 
184 void
format_power(char * str,size_t size,long power)185 format_power(char * str, size_t size, long power)
186 {
187   num_to_ansi_unit(str, size, power, 'w');
188 }
189 
190 int
min_int(int i1,int i2)191 min_int (int i1, int i2)
192 {
193   return i1 < i2 ? i1 : i2;
194 }
195 
196 int
max_int(int i1,int i2)197 max_int (int i1, int i2)
198 {
199   return i1 > i2 ? i1 : i2;
200 }
201 
202 void *
lcalloc(size_t size)203 lcalloc (size_t size)
204 {
205   void * tmp;
206   tmp = malloc(size);
207   if (tmp == NULL) {
208     printf("couldn't malloc %d bytes!  Dying.\n",size);
209     exit(-1);
210   }
211 
212   return tmp;
213 }
214