LibIRCClient 1.10 Used by Probotic
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
Ce dépôt est archivé. Vous pouvez voir les fichiers et le cloner, mais vous ne pouvez pas pousser ni ouvrir de ticket/demande d'ajout.

389 lignes
8.4KB

  1. /*
  2. * Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
  3. *
  4. * This library is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or (at your
  7. * option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  12. * License for more details.
  13. */
  14. #include <ctype.h>
  15. #define LIBIRC_COLORPARSER_BOLD (1<<1)
  16. #define LIBIRC_COLORPARSER_UNDERLINE (1<<2)
  17. #define LIBIRC_COLORPARSER_REVERSE (1<<3)
  18. #define LIBIRC_COLORPARSER_COLOR (1<<4)
  19. #define LIBIRC_COLORPARSER_MAXCOLORS 15
  20. static const char * color_replacement_table[] =
  21. {
  22. "WHITE",
  23. "BLACK",
  24. "DARKBLUE",
  25. "DARKGREEN",
  26. "RED",
  27. "BROWN",
  28. "PURPLE",
  29. "OLIVE",
  30. "YELLOW",
  31. "GREEN",
  32. "TEAL",
  33. "CYAN",
  34. "BLUE",
  35. "MAGENTA",
  36. "DARKGRAY",
  37. "LIGHTGRAY",
  38. 0
  39. };
  40. static inline void libirc_colorparser_addorcat (char ** destline, unsigned int * destlen, const char * str)
  41. {
  42. unsigned int len = strlen(str);
  43. if ( *destline )
  44. {
  45. strcpy (*destline, str);
  46. *destline += len;
  47. }
  48. else
  49. *destlen += len;
  50. }
  51. static void libirc_colorparser_applymask (unsigned int * mask,
  52. char ** destline, unsigned int * destlen,
  53. unsigned int bitmask, const char * start, const char * end)
  54. {
  55. if ( (*mask & bitmask) != 0 )
  56. {
  57. *mask &= ~bitmask;
  58. libirc_colorparser_addorcat (destline, destlen, end);
  59. }
  60. else
  61. {
  62. *mask |= bitmask;
  63. libirc_colorparser_addorcat (destline, destlen, start);
  64. }
  65. }
  66. static void libirc_colorparser_applycolor (unsigned int * mask,
  67. char ** destline, unsigned int * destlen,
  68. unsigned int colorid, unsigned int bgcolorid)
  69. {
  70. const char * end = "[/COLOR]";
  71. char startbuf[64];
  72. if ( bgcolorid != 0 )
  73. sprintf (startbuf, "[COLOR=%s/%s]", color_replacement_table[colorid], color_replacement_table[bgcolorid]);
  74. else
  75. sprintf (startbuf, "[COLOR=%s]", color_replacement_table[colorid]);
  76. if ( (*mask & LIBIRC_COLORPARSER_COLOR) != 0 )
  77. libirc_colorparser_addorcat (destline, destlen, end);
  78. *mask |= LIBIRC_COLORPARSER_COLOR;
  79. libirc_colorparser_addorcat (destline, destlen, startbuf);
  80. }
  81. static void libirc_colorparser_closetags (unsigned int * mask,
  82. char ** destline, unsigned int * destlen)
  83. {
  84. if ( *mask & LIBIRC_COLORPARSER_BOLD )
  85. libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_BOLD, 0, "[/B]");
  86. if ( *mask & LIBIRC_COLORPARSER_UNDERLINE )
  87. libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_UNDERLINE, 0, "[/U]");
  88. if ( *mask & LIBIRC_COLORPARSER_REVERSE )
  89. libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_REVERSE, 0, "[/I]");
  90. if ( *mask & LIBIRC_COLORPARSER_COLOR )
  91. libirc_colorparser_applymask (mask, destline, destlen, LIBIRC_COLORPARSER_COLOR, 0, "[/COLOR]");
  92. }
  93. /*
  94. * IRC to [code] color conversion. Or strip.
  95. */
  96. static char * libirc_colorparser_irc2code (const char * source, int strip)
  97. {
  98. unsigned int mask = 0, destlen = 0;
  99. char * destline = 0, *d = 0;
  100. const char *p;
  101. int current_bg = 0;
  102. /*
  103. * There will be two passes. First pass calculates the total length of
  104. * the destination string. The second pass allocates memory for the string,
  105. * and fills it.
  106. */
  107. while ( destline == 0 ) // destline will be set after the 2nd pass
  108. {
  109. if ( destlen > 0 )
  110. {
  111. // This is the 2nd pass; allocate memory.
  112. if ( (destline = malloc (destlen)) == 0 )
  113. return 0;
  114. d = destline;
  115. }
  116. for ( p = source; *p; p++ )
  117. {
  118. switch (*p)
  119. {
  120. case 0x02: // bold
  121. if ( strip )
  122. continue;
  123. libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_BOLD, "[B]", "[/B]");
  124. break;
  125. case 0x1F: // underline
  126. if ( strip )
  127. continue;
  128. libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_UNDERLINE, "[U]", "[/U]");
  129. break;
  130. case 0x16: // reverse
  131. if ( strip )
  132. continue;
  133. libirc_colorparser_applymask (&mask, &d, &destlen, LIBIRC_COLORPARSER_REVERSE, "[I]", "[/I]");
  134. break;
  135. case 0x0F: // reset colors
  136. if ( strip )
  137. continue;
  138. libirc_colorparser_closetags (&mask, &d, &destlen);
  139. break;
  140. case 0x03: // set color
  141. if ( isdigit (p[1]) )
  142. {
  143. // Parse
  144. int bgcolor = -1, color = p[1] - 0x30;
  145. p++;
  146. if ( isdigit (p[1]) )
  147. {
  148. color = color * 10 + (p[1] - 0x30);
  149. p++;
  150. }
  151. // If there is a comma, search for the following
  152. // background color
  153. if ( p[1] == ',' && isdigit (p[2]) )
  154. {
  155. bgcolor = p[2] - 0x30;
  156. p += 2;
  157. if ( isdigit (p[1]) )
  158. {
  159. bgcolor = bgcolor * 10 + (p[1] - 0x30);
  160. p++;
  161. }
  162. }
  163. // Check for range
  164. if ( color <= LIBIRC_COLORPARSER_MAXCOLORS
  165. && bgcolor <= LIBIRC_COLORPARSER_MAXCOLORS )
  166. {
  167. if ( strip )
  168. continue;
  169. if ( bgcolor != -1 )
  170. current_bg = bgcolor;
  171. libirc_colorparser_applycolor (&mask, &d, &destlen, color, current_bg);
  172. }
  173. }
  174. break;
  175. default:
  176. if ( destline )
  177. *d++ = *p;
  178. else
  179. destlen++;
  180. break;
  181. }
  182. }
  183. // Close all the opened tags
  184. libirc_colorparser_closetags (&mask, &d, &destlen);
  185. destlen++; // for 0-terminator
  186. }
  187. *d = '\0';
  188. return destline;
  189. }
  190. static int libirc_colorparser_colorlookup (const char * color)
  191. {
  192. int i;
  193. for ( i = 0; color_replacement_table[i]; i++ )
  194. if ( !strcmp (color, color_replacement_table[i]) )
  195. return i;
  196. return -1;
  197. }
  198. /*
  199. * [code] to IRC color conversion.
  200. */
  201. char * irc_color_convert_to_mirc (const char * source)
  202. {
  203. unsigned int destlen = 0;
  204. char * destline = 0, *d = 0;
  205. const char *p1, *p2, *cur;
  206. /*
  207. * There will be two passes. First pass calculates the total length of
  208. * the destination string. The second pass allocates memory for the string,
  209. * and fills it.
  210. */
  211. while ( destline == 0 ) // destline will be set after the 2nd pass
  212. {
  213. if ( destlen > 0 )
  214. {
  215. // This is the 2nd pass; allocate memory.
  216. if ( (destline = malloc (destlen)) == 0 )
  217. return 0;
  218. d = destline;
  219. }
  220. cur = source;
  221. while ( (p1 = strchr (cur, '[')) != 0 )
  222. {
  223. const char * replacedval = 0;
  224. p2 = 0;
  225. // Check if the closing bracket is available after p1
  226. // and the tag length is suitable
  227. if ( p1[1] != '\0'
  228. && (p2 = strchr (p1, ']')) != 0
  229. && (p2 - p1) > 1
  230. && (p2 - p1) < 31 )
  231. {
  232. // Get the tag
  233. char tagbuf[32];
  234. int taglen = p2 - p1 - 1;
  235. memcpy (tagbuf, p1 + 1, taglen);
  236. tagbuf[taglen] = '\0';
  237. if ( !strcmp (tagbuf, "/COLOR") )
  238. replacedval = "\x0F";
  239. else if ( strstr (tagbuf, "COLOR=") == tagbuf )
  240. {
  241. int color, bgcolor = -2;
  242. char * bcol;
  243. bcol = strchr (tagbuf + 6, '/');
  244. if ( bcol )
  245. {
  246. *bcol++ = '\0';
  247. bgcolor = libirc_colorparser_colorlookup (bcol);
  248. }
  249. color = libirc_colorparser_colorlookup (tagbuf + 6);
  250. if ( color != -1 && bgcolor == -2 )
  251. {
  252. sprintf (tagbuf, "\x03%02d", color);
  253. replacedval = tagbuf;
  254. }
  255. else if ( color != -1 && bgcolor >= 0 )
  256. {
  257. sprintf (tagbuf, "\x03%02d,%02d", color, bgcolor);
  258. replacedval = tagbuf;
  259. }
  260. }
  261. else if ( !strcmp (tagbuf, "B") || !strcmp (tagbuf, "/B") )
  262. replacedval = "\x02";
  263. else if ( !strcmp (tagbuf, "U") || !strcmp (tagbuf, "/U") )
  264. replacedval = "\x1F";
  265. else if ( !strcmp (tagbuf, "I") || !strcmp (tagbuf, "/I") )
  266. replacedval = "\x16";
  267. }
  268. if ( replacedval )
  269. {
  270. // add a part before the tag
  271. int partlen = p1 - cur;
  272. if ( destline )
  273. {
  274. memcpy (d, cur, partlen);
  275. d += partlen;
  276. }
  277. else
  278. destlen += partlen;
  279. // Add the replacement
  280. libirc_colorparser_addorcat (&d, &destlen, replacedval);
  281. // And move the pointer
  282. cur = p2 + 1;
  283. }
  284. else
  285. {
  286. // add a whole part before the end tag
  287. int partlen;
  288. if ( !p2 )
  289. p2 = cur + strlen(cur);
  290. partlen = p2 - cur + 1;
  291. if ( destline )
  292. {
  293. memcpy (d, cur, partlen);
  294. d += partlen;
  295. }
  296. else
  297. destlen += partlen;
  298. // And move the pointer
  299. cur = p2 + 1;
  300. }
  301. }
  302. // Add the rest of string
  303. libirc_colorparser_addorcat (&d, &destlen, cur);
  304. destlen++; // for 0-terminator
  305. }
  306. *d = '\0';
  307. return destline;
  308. }
  309. char * irc_color_strip_from_mirc (const char * message)
  310. {
  311. return libirc_colorparser_irc2code (message, 1);
  312. }
  313. char * irc_color_convert_from_mirc (const char * message)
  314. {
  315. return libirc_colorparser_irc2code (message, 0);
  316. }