PageRenderTime 22ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rxvt-2-7-0/src/misc.c

#
C | 399 lines | 258 code | 45 blank | 96 comment | 89 complexity | 7c7c1af115595acca8c3622cdcf3c86c MD5 | raw file
  1. /*--------------------------------*-C-*---------------------------------*
  2. * File: misc.c
  3. *----------------------------------------------------------------------*
  4. * $Id: misc.c 611 1999-08-03 12:58:38Z mason $
  5. *
  6. * All portions of code are copyright by their respective author/s.
  7. * Copyright (C) 1996 mj olesen <olesen@me.QueensU.CA> Queen's Univ at Kingston
  8. * Copyright (C) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de>
  9. * Copyright (C) 1998,1999 Geoff Wing <gcw@pobox.com>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. *----------------------------------------------------------------------*/
  25. #include "../config.h" /* NECESSARY */
  26. #include "rxvt.h" /* NECESSARY */
  27. #include "misc.intpro" /* PROTOS for internal routines */
  28. /* EXTPROTO */
  29. char *
  30. r_basename(const char *str)
  31. {
  32. char *base = STRRCHR(str, '/');
  33. return (char *)(base ? base + 1 : str);
  34. }
  35. /*
  36. * Print an error message
  37. */
  38. /* EXTPROTO */
  39. void
  40. print_error(const char *fmt,...)
  41. {
  42. va_list arg_ptr;
  43. va_start(arg_ptr, fmt);
  44. fprintf(stderr, APL_NAME ": ");
  45. vfprintf(stderr, fmt, arg_ptr);
  46. fprintf(stderr, "\n");
  47. va_end(arg_ptr);
  48. }
  49. /*
  50. * check that the first characters of S1 match S2
  51. *
  52. * No Match
  53. * return: 0
  54. * Match
  55. * return: STRLEN (S2)
  56. */
  57. /* EXTPROTO */
  58. int
  59. Str_match(const char *s1, const char *s2)
  60. {
  61. int n = STRLEN(s2);
  62. return ((STRNCMP(s1, s2, n) == 0) ? n : 0);
  63. }
  64. /* EXTPROTO */
  65. const char *
  66. Str_skip_space(const char *str)
  67. {
  68. if (str)
  69. while (*str && isspace(*str))
  70. str++;
  71. return str;
  72. }
  73. /*
  74. * remove leading/trailing space and strip-off leading/trailing quotes.
  75. * in place.
  76. */
  77. /* EXTPROTO */
  78. char *
  79. Str_trim(char *str)
  80. {
  81. char *r, *s;
  82. int n;
  83. if (!str)
  84. return NULL;
  85. if (!*str) /* shortcut */
  86. return str;
  87. /* skip leading spaces */
  88. for (s = str; *s && isspace(*s); s++) ;
  89. /* goto end of string */
  90. for (n = 0, r = s; *r++; n++) ;
  91. r -= 2;
  92. /* dump return */
  93. if (n > 0 && *r == '\n')
  94. n--, r--;
  95. /* backtrack along trailing spaces */
  96. for (; n > 0 && isspace(*r); r--, n--) ;
  97. /* skip matching leading/trailing quotes */
  98. if (*s == '"' && *r == '"' && n > 1) {
  99. s++;
  100. n -= 2;
  101. }
  102. /* copy back over: forwards copy */
  103. for (r = str; n; n--)
  104. *r++ = *s++;
  105. *r = '\0';
  106. return str;
  107. }
  108. /*
  109. * in-place interpretation of string:
  110. *
  111. * backslash-escaped: "\a\b\E\e\n\r\t", "\octal"
  112. * Ctrl chars: ^@ .. ^_, ^?
  113. *
  114. * Emacs-style: "M-" prefix
  115. *
  116. * Also,
  117. * "M-x" prefixed strings, append "\r" if needed
  118. * "\E]" prefixed strings (XTerm escape sequence) append "\a" if needed
  119. *
  120. * returns the converted string length
  121. */
  122. /* EXTPROTO */
  123. int
  124. Str_escaped(char *str)
  125. {
  126. char ch, *s, *d;
  127. int i, num, append = 0;
  128. if (!str || !*str)
  129. return 0;
  130. d = s = str;
  131. if (*s == 'M' && s[1] == '-') {
  132. /* Emacs convenience, replace leading `M-..' with `\E..' */
  133. *d++ = '\033';
  134. s += 2;
  135. if (toupper(*s) == 'X')
  136. /* append carriage-return for `M-xcommand' */
  137. for (*d++ = 'x', append = '\r', s++; isspace(*s); s++) ;
  138. }
  139. for (; (ch = *s++);) {
  140. if (ch == '\\') {
  141. switch ((ch = *s++)) {
  142. case '0': /* octal */
  143. case '1': /* octal */
  144. case '2': /* octal */
  145. case '3': /* octal */
  146. case '4': /* octal */
  147. case '5': /* octal */
  148. case '6': /* octal */
  149. case '7': /* octal */
  150. num = ch - '0';
  151. for (i = 0; i < 2; i++, s++) {
  152. ch = *s;
  153. if (ch < '0' || ch > '7')
  154. break;
  155. num = num * 8 + ch - '0';
  156. }
  157. ch = (char)num;
  158. break;
  159. case 'a': /* bell */
  160. ch = 007;
  161. break;
  162. case 'b': /* backspace */
  163. ch = '\b';
  164. break;
  165. case 'E': /* escape */
  166. case 'e':
  167. ch = 033;
  168. break;
  169. case 'n': /* newline */
  170. ch = '\n';
  171. break;
  172. case 'r': /* carriage-return */
  173. ch = '\r';
  174. break;
  175. case 't': /* tab */
  176. ch = '\t';
  177. break;
  178. }
  179. } else if (ch == '^') {
  180. ch = *s++;
  181. ch = toupper(ch);
  182. ch = (ch == '?' ? 127 : (ch - '@'));
  183. }
  184. *d++ = ch;
  185. }
  186. /* ESC] is an XTerm escape sequence, must be ^G terminated */
  187. if (*str == '\0' && str[1] == '\033' && str[2] == ']')
  188. append = 007;
  189. /* add trailing character as required */
  190. if (append && d[-1] != append)
  191. *d++ = append;
  192. *d = '\0';
  193. return (d - str);
  194. }
  195. /*----------------------------------------------------------------------*
  196. * file searching
  197. */
  198. /* #define DEBUG_SEARCH_PATH */
  199. #if defined (XPM_BACKGROUND) || (MENUBAR_MAX)
  200. /*
  201. * search for FILE in the current working directory, and within the
  202. * colon-delimited PATHLIST, adding the file extension EXT if required.
  203. *
  204. * FILE is either semi-colon or zero terminated
  205. */
  206. /* INTPROTO */
  207. char *
  208. File_search_path(const char *pathlist, const char *file, const char *ext)
  209. {
  210. int maxpath, len;
  211. const char *p, *path;
  212. char name[256];
  213. if (!access(file, R_OK)) /* found (plain name) in current directory */
  214. return strdup(file);
  215. /* semi-colon delimited */
  216. if ((p = STRCHR(file, ';')))
  217. len = (p - file);
  218. else
  219. len = STRLEN(file);
  220. #ifdef DEBUG_SEARCH_PATH
  221. getcwd(name, sizeof(name));
  222. fprintf(stderr, "pwd: \"%s\"\n", name);
  223. fprintf(stderr, "find: \"%.*s\"\n", len, file);
  224. #endif
  225. /* leave room for an extra '/' and trailing '\0' */
  226. maxpath = sizeof(name) - (len + (ext ? STRLEN(ext) : 0) + 2);
  227. if (maxpath <= 0)
  228. return NULL;
  229. /* check if we can find it now */
  230. STRNCPY(name, file, len);
  231. name[len] = '\0';
  232. if (!access(name, R_OK))
  233. return strdup(name);
  234. if (ext) {
  235. STRCAT(name, ext);
  236. if (!access(name, R_OK))
  237. return strdup(name);
  238. }
  239. for (path = pathlist; path != NULL && *path != '\0'; path = p) {
  240. int n;
  241. /* colon delimited */
  242. if ((p = STRCHR(path, ':')) == NULL)
  243. p = STRCHR(path, '\0');
  244. n = (p - path);
  245. if (*p != '\0')
  246. p++;
  247. if (n > 0 && n <= maxpath) {
  248. STRNCPY(name, path, n);
  249. if (name[n - 1] != '/')
  250. name[n++] = '/';
  251. name[n] = '\0';
  252. STRNCAT(name, file, len);
  253. if (!access(name, R_OK))
  254. return strdup(name);
  255. if (ext) {
  256. STRCAT(name, ext);
  257. if (!access(name, R_OK))
  258. return strdup(name);
  259. }
  260. }
  261. }
  262. return NULL;
  263. }
  264. /* EXTPROTO */
  265. char *
  266. File_find(const char *file, const char *ext)
  267. {
  268. char *f;
  269. if (file == NULL || *file == '\0')
  270. return NULL;
  271. /* search environment variables here too */
  272. if ((f = File_search_path(rs[Rs_path], file, ext)) == NULL)
  273. #ifdef PATH_ENV
  274. if ((f = File_search_path(getenv(PATH_ENV), file, ext)) == NULL)
  275. #endif
  276. f = File_search_path(getenv("PATH"), file, ext);
  277. #ifdef DEBUG_SEARCH_PATH
  278. if (f)
  279. fprintf(stderr, "found: \"%s\"\n", f);
  280. #endif
  281. return f;
  282. }
  283. #endif /* defined (XPM_BACKGROUND) || (MENUBAR_MAX) */
  284. /*----------------------------------------------------------------------*
  285. * miscellaneous drawing routines
  286. */
  287. /*
  288. * Draw top/left and bottom/right border shadows around windows
  289. */
  290. #if (! defined(NEXT_SCROLLBAR) && ! defined(XTERM_SCROLLBAR)) || defined(MENUBAR)
  291. /* EXTPROTO */
  292. void
  293. Draw_Shadow(Window win, GC topShadow, GC botShadow, int x, int y, int w, int h)
  294. {
  295. int x1, y1, w1, h1, shadow;
  296. shadow = (w == 0 || h == 0) ? 1 : SHADOW;
  297. w1 = w + x - 1;
  298. h1 = h + y - 1;
  299. x1 = x;
  300. y1 = y;
  301. for (; shadow-- > 0; x1++, y1++, w1--, h1--) {
  302. XDrawLine(Xdisplay, win, topShadow, x1, y1, w1, y1);
  303. XDrawLine(Xdisplay, win, topShadow, x1, y1, x1, h1);
  304. }
  305. shadow = (w == 0 || h == 0) ? 1 : SHADOW;
  306. w1 = w + x - 1;
  307. h1 = h + y - 1;
  308. x1 = x + 1;
  309. y1 = y + 1;
  310. for (; shadow-- > 0; x1++, y1++, w1--, h1--) {
  311. XDrawLine(Xdisplay, win, botShadow, w1, h1, w1, y1);
  312. XDrawLine(Xdisplay, win, botShadow, w1, h1, x1, h1);
  313. }
  314. }
  315. #endif
  316. /* button shapes */
  317. #ifdef MENUBAR
  318. /* EXTPROTO */
  319. void
  320. Draw_Triangle(Window win, GC topShadow, GC botShadow, int x, int y, int w, int type)
  321. {
  322. switch (type) {
  323. case 'r': /* right triangle */
  324. XDrawLine(Xdisplay, win, topShadow, x, y, x, y + w);
  325. XDrawLine(Xdisplay, win, topShadow, x, y, x + w, y + w / 2);
  326. XDrawLine(Xdisplay, win, botShadow, x, y + w, x + w, y + w / 2);
  327. break;
  328. case 'l': /* right triangle */
  329. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x + w, y);
  330. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x, y + w / 2);
  331. XDrawLine(Xdisplay, win, topShadow, x, y + w / 2, x + w, y);
  332. break;
  333. case 'd': /* down triangle */
  334. XDrawLine(Xdisplay, win, topShadow, x, y, x + w / 2, y + w);
  335. XDrawLine(Xdisplay, win, topShadow, x, y, x + w, y);
  336. XDrawLine(Xdisplay, win, botShadow, x + w, y, x + w / 2, y + w);
  337. break;
  338. case 'u': /* up triangle */
  339. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x + w / 2, y);
  340. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x, y + w);
  341. XDrawLine(Xdisplay, win, topShadow, x, y + w, x + w / 2, y);
  342. break;
  343. #if 0
  344. case 's': /* square */
  345. XDrawLine(Xdisplay, win, topShadow, x + w, y, x, y);
  346. XDrawLine(Xdisplay, win, topShadow, x, y, x, y + w);
  347. XDrawLine(Xdisplay, win, botShadow, x, y + w, x + w, y + w);
  348. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x + w, y);
  349. break;
  350. #endif
  351. }
  352. }
  353. #endif
  354. /*----------------------- end-of-file (C source) -----------------------*/