(strobj_is_null,strobj_realloc): New function.
(print_string): Accept an explicit width argument. (print_obj): New function. (mh_format): Use the new functions. (builtin_lit): Fixed. (builtin_formataddr,builtin_putaddr): Implemented.
Showing
1 changed file
with
65 additions
and
22 deletions
... | @@ -65,6 +65,7 @@ strobj_free (strobj_t *obj) | ... | @@ -65,6 +65,7 @@ strobj_free (strobj_t *obj) |
65 | 65 | ||
66 | #define strobj_ptr(p) ((p)->ptr ? (p)->ptr : "") | 66 | #define strobj_ptr(p) ((p)->ptr ? (p)->ptr : "") |
67 | #define strobj_len(p) strlen((p)->ptr) | 67 | #define strobj_len(p) strlen((p)->ptr) |
68 | #define strobj_is_null(p) ((p)->ptr == NULL) | ||
68 | #define strobj_is_static(p) ((p)->size == 0) | 69 | #define strobj_is_static(p) ((p)->size == 0) |
69 | 70 | ||
70 | static void | 71 | static void |
... | @@ -102,7 +103,9 @@ strobj_assign (strobj_t *lvalue, strobj_t *rvalue) | ... | @@ -102,7 +103,9 @@ strobj_assign (strobj_t *lvalue, strobj_t *rvalue) |
102 | static void | 103 | static void |
103 | strobj_copy (strobj_t *lvalue, strobj_t *rvalue) | 104 | strobj_copy (strobj_t *lvalue, strobj_t *rvalue) |
104 | { | 105 | { |
105 | if (lvalue->size >= strobj_len (rvalue) + 1) | 106 | if (strobj_is_null (rvalue)) |
107 | strobj_free (lvalue); | ||
108 | else if (lvalue->size >= strobj_len (rvalue) + 1) | ||
106 | memcpy (lvalue->ptr, strobj_ptr (rvalue), strobj_len (rvalue) + 1); | 109 | memcpy (lvalue->ptr, strobj_ptr (rvalue), strobj_len (rvalue) + 1); |
107 | else | 110 | else |
108 | { | 111 | { |
... | @@ -112,6 +115,25 @@ strobj_copy (strobj_t *lvalue, strobj_t *rvalue) | ... | @@ -112,6 +115,25 @@ strobj_copy (strobj_t *lvalue, strobj_t *rvalue) |
112 | } | 115 | } |
113 | } | 116 | } |
114 | 117 | ||
118 | static void | ||
119 | strobj_realloc (strobj_t *obj, size_t length) | ||
120 | { | ||
121 | if (strobj_is_static (obj)) | ||
122 | { | ||
123 | char *value = strobj_ptr (obj); | ||
124 | obj->ptr = xmalloc (length); | ||
125 | strncpy (obj->ptr, value, length-1); | ||
126 | obj->ptr[length-1] = 0; | ||
127 | obj->size = length; | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | obj->ptr = xrealloc (obj->ptr, length); | ||
132 | obj->ptr[length-1] = 0; | ||
133 | obj->size = length; | ||
134 | } | ||
135 | } | ||
136 | |||
115 | /* Compress whitespace in a string */ | 137 | /* Compress whitespace in a string */ |
116 | static void | 138 | static void |
117 | compress_ws (char *str, size_t *size) | 139 | compress_ws (char *str, size_t *size) |
... | @@ -141,12 +163,14 @@ compress_ws (char *str, size_t *size) | ... | @@ -141,12 +163,14 @@ compress_ws (char *str, size_t *size) |
141 | 163 | ||
142 | /* Print len bytes from str into mach->outbuf */ | 164 | /* Print len bytes from str into mach->outbuf */ |
143 | static void | 165 | static void |
144 | print_string (struct mh_machine *mach, char *str, size_t len) | 166 | print_string (struct mh_machine *mach, size_t width, char *str, size_t len) |
145 | { | 167 | { |
146 | size_t rest = strlen (str); | 168 | size_t rest = strlen (str); |
147 | 169 | ||
148 | if (len > rest) | 170 | if (len > rest) |
149 | len = rest; | 171 | len = rest; |
172 | if (!width) | ||
173 | width = mach->width; | ||
150 | rest = mach->width - mach->ind; | 174 | rest = mach->width - mach->ind; |
151 | if (len > rest) | 175 | if (len > rest) |
152 | len = rest; | 176 | len = rest; |
... | @@ -155,6 +179,13 @@ print_string (struct mh_machine *mach, char *str, size_t len) | ... | @@ -155,6 +179,13 @@ print_string (struct mh_machine *mach, char *str, size_t len) |
155 | } | 179 | } |
156 | 180 | ||
157 | static void | 181 | static void |
182 | print_obj (struct mh_machine *mach, size_t width, strobj_t *obj) | ||
183 | { | ||
184 | if (!strobj_is_null (obj)) | ||
185 | print_string (mach, 0, strobj_ptr (obj), strobj_len (obj)); | ||
186 | } | ||
187 | |||
188 | static void | ||
158 | reset_fmt_defaults (struct mh_machine *mach) | 189 | reset_fmt_defaults (struct mh_machine *mach) |
159 | { | 190 | { |
160 | mach->fmtflags = 0; | 191 | mach->fmtflags = 0; |
... | @@ -335,7 +366,7 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno, | ... | @@ -335,7 +366,7 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno, |
335 | else | 366 | else |
336 | ptr = buf; | 367 | ptr = buf; |
337 | 368 | ||
338 | print_string (&mach, ptr, strlen (ptr)); | 369 | print_string (&mach, 0, ptr, strlen (ptr)); |
339 | reset_fmt_defaults (&mach); | 370 | reset_fmt_defaults (&mach); |
340 | } | 371 | } |
341 | break; | 372 | break; |
... | @@ -357,15 +388,11 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno, | ... | @@ -357,15 +388,11 @@ mh_format (mh_format_t *fmt, message_t msg, size_t msgno, |
357 | mach.outbuf[mach.ind] = padchar; | 388 | mach.outbuf[mach.ind] = padchar; |
358 | } | 389 | } |
359 | 390 | ||
360 | print_string (&mach, strobj_ptr (&mach.reg_str), fmtwidth); | 391 | print_string (&mach, 0, strobj_ptr (&mach.reg_str), fmtwidth); |
361 | reset_fmt_defaults (&mach); | 392 | reset_fmt_defaults (&mach); |
362 | } | 393 | } |
363 | else if (mach.reg_str.ptr) | 394 | else |
364 | { | 395 | print_obj (&mach, 0, &mach.reg_str); |
365 | print_string (&mach, | ||
366 | strobj_ptr (&mach.reg_str), | ||
367 | strobj_len (&mach.reg_str)); | ||
368 | } | ||
369 | break; | 396 | break; |
370 | 397 | ||
371 | case mhop_fmtspec: | 398 | case mhop_fmtspec: |
... | @@ -537,7 +564,7 @@ builtin_num (struct mh_machine *mach) | ... | @@ -537,7 +564,7 @@ builtin_num (struct mh_machine *mach) |
537 | static void | 564 | static void |
538 | builtin_lit (struct mh_machine *mach) | 565 | builtin_lit (struct mh_machine *mach) |
539 | { | 566 | { |
540 | strobj_assign (&mach->reg_str, &mach->arg_str); | 567 | /* do nothing */ |
541 | } | 568 | } |
542 | 569 | ||
543 | static void | 570 | static void |
... | @@ -648,7 +675,7 @@ _parse_date (struct mh_machine *mach, struct tm *tm, mu_timezone *tz) | ... | @@ -648,7 +675,7 @@ _parse_date (struct mh_machine *mach, struct tm *tm, mu_timezone *tz) |
648 | char *date = strobj_ptr (&mach->arg_str); | 675 | char *date = strobj_ptr (&mach->arg_str); |
649 | const char *p = date; | 676 | const char *p = date; |
650 | 677 | ||
651 | if (parse822_date_time(&p, date+strlen(date), tm, tz)) | 678 | if (parse822_date_time (&p, date+strlen(date), tm, tz)) |
652 | { | 679 | { |
653 | mh_error ("can't parse date: [%s]", date); | 680 | mh_error ("can't parse date: [%s]", date); |
654 | return -1; | 681 | return -1; |
... | @@ -1201,7 +1228,7 @@ static void | ... | @@ -1201,7 +1228,7 @@ static void |
1201 | builtin_formataddr (struct mh_machine *mach) | 1228 | builtin_formataddr (struct mh_machine *mach) |
1202 | { | 1229 | { |
1203 | address_t addr; | 1230 | address_t addr; |
1204 | size_t num = 0, n, i; | 1231 | size_t num = 0, n, i, length = 0, reglen; |
1205 | char buf[80], *p; | 1232 | char buf[80], *p; |
1206 | 1233 | ||
1207 | if (address_create (&addr, strobj_ptr (&mach->arg_str))) | 1234 | if (address_create (&addr, strobj_ptr (&mach->arg_str))) |
... | @@ -1209,19 +1236,35 @@ builtin_formataddr (struct mh_machine *mach) | ... | @@ -1209,19 +1236,35 @@ builtin_formataddr (struct mh_machine *mach) |
1209 | address_get_count (addr, &num); | 1236 | address_get_count (addr, &num); |
1210 | for (i = 1; i <= num; i++) | 1237 | for (i = 1; i <= num; i++) |
1211 | { | 1238 | { |
1239 | if (address_get_personal (addr, i, buf, sizeof buf, &n) == 0 | ||
1240 | && n != 0) | ||
1241 | length += n+1; /* + space */ | ||
1212 | address_get_email (addr, i, buf, sizeof buf, &n); | 1242 | address_get_email (addr, i, buf, sizeof buf, &n); |
1213 | num += n+1; | 1243 | length += n+3; /* two brackets + (eventual) comma */ |
1214 | } | 1244 | } |
1215 | 1245 | ||
1216 | num += strobj_len (&mach->reg_str) + 1; | 1246 | if (strobj_is_null (&mach->reg_str)) |
1217 | mach->reg_str.ptr = xrealloc (mach->reg_str.ptr, num); | 1247 | reglen = 0; |
1218 | mach->reg_str.size = num + 1; | 1248 | else |
1219 | p = strobj_ptr (&mach->reg_str) + strobj_len (&mach->reg_str) ; | 1249 | reglen = strobj_len (&mach->reg_str); |
1250 | length += reglen + 1; | ||
1251 | strobj_realloc (&mach->reg_str, length); | ||
1252 | p = strobj_ptr (&mach->reg_str) + reglen; | ||
1220 | for (i = 1; i <= num; i++) | 1253 | for (i = 1; i <= num; i++) |
1221 | { | 1254 | { |
1255 | if (reglen > 0) | ||
1256 | *p++ = ','; | ||
1257 | if (address_get_personal (addr, i, buf, sizeof buf, &n) == 0 && n > 0) | ||
1258 | { | ||
1259 | memcpy (p, buf, n); | ||
1260 | p += n; | ||
1261 | *p++ = ' '; | ||
1262 | } | ||
1222 | address_get_email (addr, i, buf, sizeof buf, &n); | 1263 | address_get_email (addr, i, buf, sizeof buf, &n); |
1264 | *p++ = '<'; | ||
1223 | memcpy (p, buf, n); | 1265 | memcpy (p, buf, n); |
1224 | p += n; | 1266 | p += n; |
1267 | *p++ = '>'; | ||
1225 | } | 1268 | } |
1226 | *p = 0; | 1269 | *p = 0; |
1227 | } | 1270 | } |
... | @@ -1232,14 +1275,14 @@ builtin_formataddr (struct mh_machine *mach) | ... | @@ -1232,14 +1275,14 @@ builtin_formataddr (struct mh_machine *mach) |
1232 | static void | 1275 | static void |
1233 | builtin_putaddr (struct mh_machine *mach) | 1276 | builtin_putaddr (struct mh_machine *mach) |
1234 | { | 1277 | { |
1235 | /*FIXME:*/ | 1278 | print_obj (mach, mach->reg_num, &mach->arg_str); |
1236 | builtin_not_implemented ("putaddr"); | 1279 | print_obj (mach, mach->reg_num, &mach->reg_str); |
1237 | } | 1280 | } |
1238 | 1281 | ||
1239 | /* Builtin function table */ | 1282 | /* Builtin function table */ |
1240 | 1283 | ||
1241 | mh_builtin_t builtin_tab[] = { | 1284 | mh_builtin_t builtin_tab[] = { |
1242 | /* Name Handling function Return type Arg type */ | 1285 | /* Name Handling function Return type Arg type Opt. arg */ |
1243 | { "msg", builtin_msg, mhtype_num, mhtype_none }, | 1286 | { "msg", builtin_msg, mhtype_num, mhtype_none }, |
1244 | { "cur", builtin_cur, mhtype_num, mhtype_none }, | 1287 | { "cur", builtin_cur, mhtype_num, mhtype_none }, |
1245 | { "size", builtin_size, mhtype_num, mhtype_none }, | 1288 | { "size", builtin_size, mhtype_num, mhtype_none }, |
... | @@ -1258,7 +1301,7 @@ mh_builtin_t builtin_tab[] = { | ... | @@ -1258,7 +1301,7 @@ mh_builtin_t builtin_tab[] = { |
1258 | { "divide", builtin_divide, mhtype_num, mhtype_num }, | 1301 | { "divide", builtin_divide, mhtype_num, mhtype_num }, |
1259 | { "modulo", builtin_modulo, mhtype_num, mhtype_num }, | 1302 | { "modulo", builtin_modulo, mhtype_num, mhtype_num }, |
1260 | { "num", builtin_num, mhtype_num, mhtype_num }, | 1303 | { "num", builtin_num, mhtype_num, mhtype_num }, |
1261 | { "lit", builtin_lit, mhtype_str, mhtype_str }, | 1304 | { "lit", builtin_lit, mhtype_str, mhtype_str, 1 }, |
1262 | { "getenv", builtin_getenv, mhtype_str, mhtype_str }, | 1305 | { "getenv", builtin_getenv, mhtype_str, mhtype_str }, |
1263 | { "profile", builtin_profile, mhtype_str, mhtype_str }, | 1306 | { "profile", builtin_profile, mhtype_str, mhtype_str }, |
1264 | { "nonzero", builtin_nonzero, mhtype_num, mhtype_num, 1 }, | 1307 | { "nonzero", builtin_nonzero, mhtype_num, mhtype_num, 1 }, | ... | ... |
-
Please register or sign in to post a comment