PageRenderTime 29ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/msys/packages/rxvt/2.7.2/src/misc.c

https://github.com/dscho/msys
C | 383 lines | 242 code | 45 blank | 96 comment | 110 complexity | 1ede76688525d5a5b584eb0141bebf8c MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0
  1. /*--------------------------------*-C-*---------------------------------*
  2. * File: misc.c
  3. *----------------------------------------------------------------------*
  4. * $Id: misc.c,v 1.1 2002-12-06 23:08:03 earnie Exp $
  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. ch = *s++;
  142. if (ch >= '0' && ch <= '7') { /* octal */
  143. num = ch - '0';
  144. for (i = 0; i < 2; i++, s++) {
  145. ch = *s;
  146. if (ch < '0' || ch > '7')
  147. break;
  148. num = num * 8 + ch - '0';
  149. }
  150. ch = (char)num;
  151. } else if (ch == 'a')
  152. ch = 007; /* bell */
  153. else if (ch == 'b')
  154. ch = '\b'; /* backspace */
  155. else if (ch == 'E' || ch == 'e')
  156. ch = 033; /* escape */
  157. else if (ch == 'n')
  158. ch = '\n'; /* newline */
  159. else if (ch == 'r')
  160. ch = '\r'; /* carriage-return */
  161. else if (ch == 't')
  162. ch = '\t'; /* tab */
  163. } else if (ch == '^') {
  164. ch = *s++;
  165. ch = toupper(ch);
  166. ch = (ch == '?' ? 127 : (ch - '@'));
  167. }
  168. *d++ = ch;
  169. }
  170. /* ESC] is an XTerm escape sequence, must be ^G terminated */
  171. if (*str == '\0' && str[1] == '\033' && str[2] == ']')
  172. append = 007;
  173. /* add trailing character as required */
  174. if (append && d[-1] != append)
  175. *d++ = append;
  176. *d = '\0';
  177. return (d - str);
  178. }
  179. /*----------------------------------------------------------------------*
  180. * file searching
  181. */
  182. /* #define DEBUG_SEARCH_PATH */
  183. #if defined (XPM_BACKGROUND) || (MENUBAR_MAX)
  184. /*
  185. * search for FILE in the current working directory, and within the
  186. * colon-delimited PATHLIST, adding the file extension EXT if required.
  187. *
  188. * FILE is either semi-colon or zero terminated
  189. */
  190. /* INTPROTO */
  191. char *
  192. File_search_path(const char *pathlist, const char *file, const char *ext)
  193. {
  194. int maxpath, len;
  195. const char *p, *path;
  196. char name[256];
  197. if (!access(file, R_OK)) /* found (plain name) in current directory */
  198. return strdup(file);
  199. /* semi-colon delimited */
  200. if ((p = STRCHR(file, ';')))
  201. len = (p - file);
  202. else
  203. len = STRLEN(file);
  204. #ifdef DEBUG_SEARCH_PATH
  205. getcwd(name, sizeof(name));
  206. fprintf(stderr, "pwd: \"%s\"\n", name);
  207. fprintf(stderr, "find: \"%.*s\"\n", len, file);
  208. #endif
  209. /* leave room for an extra '/' and trailing '\0' */
  210. maxpath = sizeof(name) - (len + (ext ? STRLEN(ext) : 0) + 2);
  211. if (maxpath <= 0)
  212. return NULL;
  213. /* check if we can find it now */
  214. STRNCPY(name, file, len);
  215. name[len] = '\0';
  216. if (!access(name, R_OK))
  217. return strdup(name);
  218. if (ext) {
  219. STRCAT(name, ext);
  220. if (!access(name, R_OK))
  221. return strdup(name);
  222. }
  223. for (path = pathlist; path != NULL && *path != '\0'; path = p) {
  224. int n;
  225. /* colon delimited */
  226. if ((p = STRCHR(path, ':')) == NULL)
  227. p = STRCHR(path, '\0');
  228. n = (p - path);
  229. if (*p != '\0')
  230. p++;
  231. if (n > 0 && n <= maxpath) {
  232. STRNCPY(name, path, n);
  233. if (name[n - 1] != '/')
  234. name[n++] = '/';
  235. name[n] = '\0';
  236. STRNCAT(name, file, len);
  237. if (!access(name, R_OK))
  238. return strdup(name);
  239. if (ext) {
  240. STRCAT(name, ext);
  241. if (!access(name, R_OK))
  242. return strdup(name);
  243. }
  244. }
  245. }
  246. return NULL;
  247. }
  248. /* EXTPROTO */
  249. char *
  250. File_find(const char *file, const char *ext)
  251. {
  252. char *f;
  253. if (file == NULL || *file == '\0')
  254. return NULL;
  255. /* search environment variables here too */
  256. if ((f = File_search_path(rs.path, file, ext)) == NULL)
  257. #ifdef PATH_ENV
  258. if ((f = File_search_path(getenv(PATH_ENV), file, ext)) == NULL)
  259. #endif
  260. f = File_search_path(getenv("PATH"), file, ext);
  261. #ifdef DEBUG_SEARCH_PATH
  262. if (f)
  263. fprintf(stderr, "found: \"%s\"\n", f);
  264. #endif
  265. return f;
  266. }
  267. #endif /* defined (XPM_BACKGROUND) || (MENUBAR_MAX) */
  268. /*----------------------------------------------------------------------*
  269. * miscellaneous drawing routines
  270. */
  271. /*
  272. * Draw top/left and bottom/right border shadows around windows
  273. */
  274. #if (! defined(NEXT_SCROLLBAR) && ! defined(XTERM_SCROLLBAR)) || defined(MENUBAR)
  275. /* EXTPROTO */
  276. void
  277. Draw_Shadow(Window win, GC topShadow, GC botShadow, int x, int y, int w, int h)
  278. {
  279. int x1, y1, w1, h1, shadow;
  280. shadow = (w == 0 || h == 0) ? 1 : SHADOW;
  281. w1 = w + x - 1;
  282. h1 = h + y - 1;
  283. x1 = x;
  284. y1 = y;
  285. for (; shadow-- > 0; x1++, y1++, w1--, h1--) {
  286. XDrawLine(Xdisplay, win, topShadow, x1, y1, w1, y1);
  287. XDrawLine(Xdisplay, win, topShadow, x1, y1, x1, h1);
  288. }
  289. shadow = (w == 0 || h == 0) ? 1 : SHADOW;
  290. w1 = w + x - 1;
  291. h1 = h + y - 1;
  292. x1 = x + 1;
  293. y1 = y + 1;
  294. for (; shadow-- > 0; x1++, y1++, w1--, h1--) {
  295. XDrawLine(Xdisplay, win, botShadow, w1, h1, w1, y1);
  296. XDrawLine(Xdisplay, win, botShadow, w1, h1, x1, h1);
  297. }
  298. }
  299. #endif
  300. /* button shapes */
  301. #ifdef MENUBAR
  302. /* EXTPROTO */
  303. void
  304. Draw_Triangle(Window win, GC topShadow, GC botShadow, int x, int y, int w, int type)
  305. {
  306. switch (type) {
  307. case 'r': /* right triangle */
  308. XDrawLine(Xdisplay, win, topShadow, x, y, x, y + w);
  309. XDrawLine(Xdisplay, win, topShadow, x, y, x + w, y + w / 2);
  310. XDrawLine(Xdisplay, win, botShadow, x, y + w, x + w, y + w / 2);
  311. break;
  312. case 'l': /* right triangle */
  313. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x + w, y);
  314. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x, y + w / 2);
  315. XDrawLine(Xdisplay, win, topShadow, x, y + w / 2, x + w, y);
  316. break;
  317. case 'd': /* down triangle */
  318. XDrawLine(Xdisplay, win, topShadow, x, y, x + w / 2, y + w);
  319. XDrawLine(Xdisplay, win, topShadow, x, y, x + w, y);
  320. XDrawLine(Xdisplay, win, botShadow, x + w, y, x + w / 2, y + w);
  321. break;
  322. case 'u': /* up triangle */
  323. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x + w / 2, y);
  324. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x, y + w);
  325. XDrawLine(Xdisplay, win, topShadow, x, y + w, x + w / 2, y);
  326. break;
  327. #if 0
  328. case 's': /* square */
  329. XDrawLine(Xdisplay, win, topShadow, x + w, y, x, y);
  330. XDrawLine(Xdisplay, win, topShadow, x, y, x, y + w);
  331. XDrawLine(Xdisplay, win, botShadow, x, y + w, x + w, y + w);
  332. XDrawLine(Xdisplay, win, botShadow, x + w, y + w, x + w, y);
  333. break;
  334. #endif
  335. }
  336. }
  337. #endif
  338. /*----------------------- end-of-file (C source) -----------------------*/