7e4c942016-04-29Chris Angelico //! IMAP.types
02751c1998-09-02Niels Möller 
a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
a20af62000-09-26Fredrik Hübinette (Hubbe) 
8b19a01998-09-07Niels Möller string imap_format(mixed x) { if (!x)
d6137d1999-03-04Henrik Grubbström (Grubba)  return "NIL";
8b19a01998-09-07Niels Möller  else if (stringp(x)) return x; else return x->format(); } string imap_format_array(array a) {
9c37b11999-02-23Henrik Grubbström (Grubba) #if 0
d2bc011999-02-23Henrik Grubbström (Grubba)  if (!sizeof(a)) {
6659452003-09-01Martin Nilsson  return "";
d2bc011999-02-23Henrik Grubbström (Grubba)  } a = Array.map(a, imap_format); string res = a[0]; for(int i=1; i < sizeof(a); i++) { if (sizeof(res) && (res[-1] == '\n')) { // Special case - No space needed. res += a[i]; } else { res += " " + a[i]; } } return res;
9c37b11999-02-23Henrik Grubbström (Grubba) #else /* !0 */ return Array.map(a, imap_format) * " "; #endif /* 0 */
8b19a01998-09-07Niels Möller }
83f18c1999-03-02Henrik Grubbström (Grubba) array imap_check_array(array a) {
6659452003-09-01Martin Nilsson  return Array.filter(a, lambda(mixed item, array index) {
d716671999-03-02Henrik Grubbström (Grubba)  index[0]++;
83f18c1999-03-02Henrik Grubbström (Grubba)  if (!item || stringp(item) || objectp(item)) { return 1; }
b996a51999-03-02Henrik Grubbström (Grubba)  werror(describe_backtrace( ({
deeec51999-03-02Henrik Grubbström (Grubba)  sprintf("Bad array element %O (%d)\n",
d716671999-03-02Henrik Grubbström (Grubba)  item, index[0]),
b996a51999-03-02Henrik Grubbström (Grubba)  backtrace() }) ));
83f18c1999-03-02Henrik Grubbström (Grubba)  return 0;
6659452003-09-01Martin Nilsson  }, ({ -1 }) );
83f18c1999-03-02Henrik Grubbström (Grubba) }
02751c1998-09-02Niels Möller /* Output types */ class imap_atom { string name; void create(string s) { name = s; } string format() { return name; } }
ac64841998-11-16Niels Möller class imap_atom_options { string name; array options; array range;
7e752b1999-03-22Henrik Grubbström (Grubba)  void create(string s, string sec, array o, array r)
ac64841998-11-16Niels Möller  { name = s;
7e752b1999-03-22Henrik Grubbström (Grubba)  options = ({ sec,
eefd111999-03-24Henrik Grubbström (Grubba)  o && sizeof(o) && imap_list(Array.map(imap_check_array(o[0]->list->atom), imap_string)) }) - ({ 0 });
ac64841998-11-16Niels Möller  range = r; } string format() {
8b9fd21999-03-22Henrik Grubbström (Grubba)  werror(sprintf("options:%O\n", options));
633a911999-03-08Henrik Grubbström (Grubba)  return upper_case(name + "[" + Array.map(options, imap_format)*" " + "]")
ac64841998-11-16Niels Möller  // NOTE: Only the start index is sent + (range ? sprintf("<%d>", range[0]) : ""); } }
02751c1998-09-02Niels Möller class imap_string { string data; void create(string s) { data = s; } string format() {
cfacb31999-03-29Henrik Grubbström (Grubba)  // Pine doesn't know about \-quoting... if (!sizeof(array_sscanf(data, "%*[^\0-\037\\\"\177-\377]%s")[0]))
02751c1998-09-02Niels Möller  return "\"" + replace(data, ({ "\"", "\\" }), ({ "\\\"", "\\\\" }) ) + "\""; else
ead9722003-01-20Martin Nilsson  return sprintf("{%d}\r\n%s", sizeof(data), data);
02751c1998-09-02Niels Möller  } } class imap_list { array data;
83f18c1999-03-02Henrik Grubbström (Grubba)  void create(array a) { data = imap_check_array(a); }
02751c1998-09-02Niels Möller 
8b19a01998-09-07Niels Möller  string format() { return "(" + imap_format_array(data) + ")"; }
02751c1998-09-02Niels Möller } class imap_prefix { array data;
83f18c1999-03-02Henrik Grubbström (Grubba)  void create(array a) { data = imap_check_array(a); }
02751c1998-09-02Niels Möller 
8b19a01998-09-07Niels Möller  string format() { return "[" + imap_format_array(data) + "]"; }
02751c1998-09-02Niels Möller } class imap_number { int value; void create(int n) { value = n; } string format() { return sprintf("%d", value); } }
2b3c571998-09-23Niels Möller  /* Input types */
3524712015-05-26Martin Nilsson // Returns -1 on error.
2b3c571998-09-23Niels Möller int string_to_number(string s) {
ead9722003-01-20Martin Nilsson  if (!sizeof(s) || (sizeof(s) > 9))
2b3c571998-09-23Niels Möller  return -1; if (sizeof(values(s) - ({ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }))) return -1; return array_sscanf(s, "%d")[0]; } class imap_set { /* Each element is either an integer, the string "*", or an * array ({ start, end }) */ array items; void create(array|void a) { items = a; }
3524712015-05-26Martin Nilsson 
2b3c571998-09-23Niels Möller  int|string string_to_number_star(string s) { return (s == "*") ? s : string_to_number(s); }
3524712015-05-26Martin Nilsson 
2b3c571998-09-23Niels Möller  int|string|array string_to_subset(string s) { int i = search(s, ":"); if (i<0) return string_to_number_star(s); int|string start = string_to_number_star(s[..i-1]); if (start < 0) return -1; int end = string_to_number_star(s[i+1..]); if (intp(end) && (end < 0)) return -1; if (end == start) return start; return ({ start, end }); }
563bd72004-01-11Martin Nilsson  this_program init(string s)
2b3c571998-09-23Niels Möller  { items = s/","; for(int i = 0; i<sizeof(items); i++) { items[i] = string_to_subset(items[i]);
3524712015-05-26Martin Nilsson 
2b3c571998-09-23Niels Möller  if (intp(items[i]) && (items[i]<0)) return 0; }
563bd72004-01-11Martin Nilsson  return this;
2b3c571998-09-23Niels Möller  } int replace_number(int|string i, int largest) { return (i == "*") ? largest : i; } array(int) expand_item(int|string|array item, int largest) { if (arrayp(item)) { int start = replace_number(item[0], largest); int end = replace_number(item[1], largest); if (end > largest) end = largest; if (end < start) return ({ });
3524712015-05-26Martin Nilsson 
2b3c571998-09-23Niels Möller  array res = allocate(end - start + 1); for(int i = start; i<= end; i++) res[i-start] = i; return res; } int i = replace_number(item, largest); return (i > largest) ? ({ }) : ({ i }); }
3524712015-05-26Martin Nilsson 
2b3c571998-09-23Niels Möller  /* Return a plain array of integers. LARGEST is the number to be * substituted for "*". Handles empty intervals, and cuts away * elements larger than LARGEST. Does not attempt to handle * overlapping intervals intelligently. */ array(int) expand(int largest) { return `+( ({}), @Array.map(items, expand_item, largest)); } }