home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / util / jade-3.0.lha / Jade / src / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-19  |  10.4 KB  |  438 lines

  1. /* misc.c -- Miscellaneous functions
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4. This file is part of Jade.
  5.  
  6. Jade is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. Jade is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with Jade; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22. #include "revision.h"
  23.  
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <stdlib.h>
  27. #include <time.h>
  28.  
  29. _PR u_char *stpblk(u_char *);
  30. _PR u_char *stpalnum(u_char *);
  31. _PR u_char *cpyalnum(u_char *, u_char *);
  32. _PR VALUE concat2(u_char *, u_char *);
  33. _PR VALUE concat3(u_char *, u_char *, u_char *);
  34. _PR void misc_init(void);
  35.  
  36. u_char *
  37. stpblk(u_char *str)
  38. {
  39.     while(*str && isspace(*str))
  40.     str++;
  41.     return(str);
  42. }
  43.  
  44. u_char *
  45. stpalnum(u_char *str)
  46. {
  47.     while(*str && isalnum(*str))
  48.     str++;
  49.     return(str);
  50. }
  51.  
  52. u_char *
  53. cpyalnum(u_char *dest, u_char *src)
  54. {
  55.     while(*src && isalnum(*src))
  56.     *dest++ = *src++;
  57.     *dest++ = 0;
  58.     return(dest);
  59. }
  60.  
  61. #ifndef HAVE_STPCPY
  62. /*
  63.  * copy src to dst, returning pointer to terminating '\0' of dst.
  64.  * Although this has a prototype in my <string.h> it doesn't seem to be
  65.  * in the actual library??
  66.  */
  67. char *
  68. stpcpy(register char *dst, register const char *src)
  69. {
  70.     while((*dst++ = *src++) != 0)
  71.     ;
  72.     return(dst - 1);
  73. }
  74. #endif /* !HAVE_STPCPY */
  75.  
  76. VALUE
  77. concat2(u_char *s1, u_char *s2)
  78. {
  79.     int len = strlen(s1) + strlen(s2);
  80.     VALUE res = valstralloc(len + 1);
  81.     stpcpy(stpcpy(VSTR(res), s1), s2);
  82.     return(res);
  83. }
  84. VALUE
  85. concat3(u_char *s1, u_char *s2, u_char *s3)
  86. {
  87.     int len = strlen(s1) + strlen(s2) + strlen(s3);
  88.     VALUE res = valstralloc(len + 1);
  89.     stpcpy(stpcpy(stpcpy(VSTR(res), s1), s2), s3);
  90.     return(res);
  91. }
  92.  
  93. _PR VALUE cmd_file_concat(VALUE args);
  94. DEFUN("file-concat", cmd_file_concat, subr_file_concat, (VALUE args), V_SubrN, DOC_file_concat) /*
  95. ::doc:file_concat::
  96. (file-concat PARTS...)
  97. Returns a string made from all the PARTS, each of which is one component of
  98. a filename. Add's `/' characters between each PART if necessary.
  99. ::end:: */
  100. {
  101.     if(CONSP(args) && STRINGP(VCAR(args)))
  102.     {
  103.     u_char buf[512];
  104.     strcpy(buf, VSTR(VCAR(args)));
  105.     args = VCDR(args);
  106.     while(CONSP(args) && STRINGP(VCAR(args)))
  107.     {
  108.         if(addfilepart(buf, VSTR(VCAR(args)), 512) == 0)
  109.         return(NULL);
  110.         args = VCDR(args);
  111.     }
  112.     return(valstrdup(buf));
  113.     }
  114.     return(NullString);
  115. }
  116.  
  117. _PR VALUE cmd_system(VALUE command);
  118. DEFUN("system", cmd_system, subr_system, (VALUE command), V_Subr1, DOC_system) /*
  119. ::doc:system::
  120. (system SHELL-COMMAND)
  121. Tells the operating-system to execute SHELL-COMMAND, returns the exit code
  122. of that command.
  123. ::end:: */
  124. {
  125.     DECLARE1(command, STRINGP);
  126.     return(newnumber(system(VSTR(command))));
  127. }
  128.  
  129. _PR VALUE cmd_substr(VALUE string, VALUE start, VALUE len);
  130. DEFUN("substr", cmd_substr, subr_substr, (VALUE string, VALUE start, VALUE len), V_Subr3, DOC_substr) /*
  131. ::doc:substr::
  132. (substr STRING START LENGTH)
  133. Returns the portion of STRING starting at character number START for
  134. LENGTH characters, a LENGTH of zero means all characters after START.
  135. ::end:: */
  136. {
  137.     int length;
  138.     DECLARE1(string, STRINGP);
  139.     DECLARE2(start, NUMBERP);
  140.     DECLARE3(len, NUMBERP);
  141.     if(VNUM(len) == 0)
  142.     length = strlen(VSTR(string)) - VNUM(start);
  143.     else
  144.     length = VNUM(len);
  145.     return(valstrdupn(VSTR(string) + VNUM(start), length));
  146. }
  147.  
  148. _PR VALUE cmd_beep(void);
  149. DEFUN("beep", cmd_beep, subr_beep, (void), V_Subr0, DOC_beep) /*
  150. ::doc:beep::
  151. (beep)
  152. Rings a bell.
  153. ::end:: */
  154. {
  155.     beep(CurrVW);
  156.     return(sym_t);
  157. }
  158.  
  159. _PR VALUE cmd_base_name(VALUE file);
  160. DEFUN("base-name", cmd_base_name, subr_base_name, (VALUE file), V_Subr1, DOC_base_name) /*
  161. ::doc:base_name::
  162. (base-name FILE-NAME)
  163. Returns the file part of FILE-NAME.
  164. ::end:: */
  165. {
  166.     DECLARE1(file, STRINGP);
  167.     return(valstrdup(filepart(VSTR(file))));
  168. }
  169.  
  170. _PR VALUE cmd_path_name(VALUE file);
  171. DEFUN("path-name", cmd_path_name, subr_path_name, (VALUE file), V_Subr1, DOC_path_name) /*
  172. ::doc:path_name::
  173. (path-name FILE-NAME)
  174. Returns the directory part of FILE-NAME.
  175. ::end:: */
  176. {
  177.     int len;
  178.     DECLARE1(file, STRINGP);
  179.     len = filepart(VSTR(file)) - VSTR(file);
  180.     return(valstrdupn(VSTR(file), len));
  181. }
  182.  
  183. _PR VALUE cmd_balance_brackets(VALUE open, VALUE close, VALUE string);
  184. DEFUN("balance-brackets", cmd_balance_brackets, subr_balance_brackets, (VALUE open, VALUE close, VALUE string), V_Subr3, DOC_balance_brackets) /*
  185. ::doc:balance_brackets::
  186. (balance-brackets OPEN-STRING CLOSE-STRING STRING)
  187. ::end:: */
  188. {
  189.     int cnt = 0;
  190.     u_char *s;
  191.     DECLARE1(open, STRINGP);
  192.     DECLARE2(close, STRINGP);
  193.     DECLARE3(string, STRINGP);
  194.     s = VSTR(string) - 1;
  195.     while((s = strpbrk(s + 1, VSTR(open))))
  196.     cnt++;
  197.     s = VSTR(string) - 1;
  198.     while((s = strpbrk(s + 1, VSTR(close))))
  199.     cnt--;
  200.     return(newnumber(cnt));
  201. }
  202.  
  203. _PR VALUE cmd_strtoc(VALUE string);
  204. DEFUN("strtoc", cmd_strtoc, subr_strtoc, (VALUE string), V_Subr1, DOC_strtoc) /*
  205. ::doc:strtoc::
  206. (strtoc STRING)
  207. Returns the first character of STRING.
  208. ::end:: */
  209. {
  210.     DECLARE1(string, STRINGP);
  211.     return(newnumber((long)*VSTR(string)));
  212. }
  213.  
  214. _PR VALUE cmd_ctostr(VALUE ch);
  215. DEFUN("ctostr", cmd_ctostr, subr_ctostr, (VALUE ch), V_Subr1, DOC_ctostr) /*
  216. ::doc:ctostr::
  217. (ctostr CHAR)
  218. Returns a one-character string containing CHAR.
  219. ::end:: */
  220. {
  221.     u_char tmp[2];
  222.     DECLARE1(ch, CHARP);
  223.     tmp[0] = (u_char)VCHAR(ch);
  224.     tmp[1] = 0;
  225.     return(valstrdup(tmp));
  226. }
  227.  
  228. _PR VALUE cmd_amiga_p(void);
  229. DEFUN("amiga-p", cmd_amiga_p, subr_amiga_p, (void), V_Subr0, DOC_amiga_p) /*
  230. ::doc:amiga_p::
  231. (amiga-p)
  232. t if running on an Amiga.
  233. ::end:: */
  234. {
  235. #ifdef HAVE_AMIGA
  236.     return(sym_t);
  237. #else
  238.     return(sym_nil);
  239. #endif
  240. }
  241. _PR VALUE cmd_x11_p(void);
  242. DEFUN("x11-p", cmd_x11_p, subr_x11_p, (void), V_Subr0, DOC_x11_p) /*
  243. ::doc:x11_p::
  244. (x11-p)
  245. t if running on the X Window System V11.
  246. ::end:: */
  247. {
  248. #ifdef HAVE_X11
  249.     return(sym_t);
  250. #else
  251.     return(sym_nil);
  252. #endif
  253. }
  254. _PR VALUE cmd_unix_p(void);
  255. DEFUN("unix-p", cmd_unix_p, subr_unix_p, (void), V_Subr0, DOC_unix_p) /*
  256. ::doc:unix_p::
  257. (unix-p)
  258. t if running under some flavour of unix.
  259. ::end:: */
  260. {
  261. #ifdef HAVE_UNIX
  262.     return(sym_t);
  263. #else
  264.     return(sym_nil);
  265. #endif
  266. }
  267.  
  268. _PR VALUE cmd_tmp_file_name(void);
  269. DEFUN("tmp-file-name", cmd_tmp_file_name, subr_tmp_file_name, (void), V_Subr0, DOC_tmp_file_name) /*
  270. ::doc:tmp_file_name::
  271. (tmp-file-name)
  272. Returns the name of a unique file.
  273. ::end:: */
  274. {
  275.     return(valstrdup(tmpnam(NULL)));
  276. }
  277.  
  278. _PR VALUE cmd_make_completion_string(VALUE args);
  279. DEFUN("make-completion-string", cmd_make_completion_string, subr_make_completion_string, (VALUE args), V_SubrN, DOC_make_completion_string) /*
  280. ::doc:make_completion_string::
  281. (make-completion-string EXISTING [POSSIBLE | POSIIBLE...])
  282. ::end:: */
  283. {
  284.     u_char *orig, *match = NULL;
  285.     int matchlen = 0, origlen;
  286.     VALUE *arg;
  287.     if(!CONSP(args))
  288.     return(NULL);
  289.     arg = VCAR(args);
  290.     DECLARE1(arg, STRINGP);
  291.     orig = VSTR(arg);
  292.     origlen = strlen(orig);
  293.     arg = ARG2;
  294.     switch(VTYPE(arg))
  295.     {
  296.     case V_Cons:
  297.     args = arg;
  298.     break;
  299.     case V_StaticString:
  300.     case V_String:
  301.     args = VCDR(args);
  302.     break;
  303.     default:
  304.     return(sym_nil);
  305.     }
  306.     while(CONSP(args))
  307.     {
  308.     arg = VCAR(args);
  309.     if(STRINGP(arg))
  310.     {
  311.         u_char *tmp = VSTR(arg);
  312.         if(mystrcmp(orig, tmp))
  313.         {
  314.         if(match)
  315.         {
  316.             u_char *tmp2 = match + origlen;
  317.             tmp += origlen;
  318.             while(*tmp2 && *tmp)
  319.             {
  320.             if(*tmp2++ != *tmp++)
  321.             {
  322.                 tmp2--;
  323.                 break;
  324.             }
  325.             }
  326.             if((tmp2 - match) < matchlen)
  327.             matchlen = tmp2 - match;
  328.         }
  329.         else
  330.         {
  331.             match = tmp;
  332.             matchlen = strlen(tmp);
  333.         }
  334.         }
  335.     }
  336.     args = VCDR(args);
  337.     }
  338.     if(match)
  339.     return(valstrdupn(match, matchlen));
  340.     return(sym_nil);
  341. }
  342.  
  343. _PR VALUE cmd_current_time(void);
  344. DEFUN("current-time", cmd_current_time, subr_current_time, (void), V_Subr0, DOC_current_time) /*
  345. ::doc:current_time::
  346. (current-time)
  347. Return some number denoting the current system time.
  348. ::end:: */
  349. {
  350.     return(newnumber(getsystime()));
  351. }
  352.  
  353. _PR VALUE cmd_current_time_string(void);
  354. DEFUN("current-time-string", cmd_current_time_string, subr_current_time_string, (void), V_Subr0, DOC_current_time_string) /*
  355. ::doc:current_time_string::
  356. (current-time-string)
  357. Returns a human-readable string defining the current date and time.
  358. ::end:: */
  359. {
  360.     char *str;
  361.     time_t tim;
  362.     time(&tim);
  363.     str = ctime(&tim);
  364.     if(str)
  365.     return(valstrdupn(str, strlen(str) - 1));
  366.     return(NULL);
  367. }
  368.  
  369. _PR VALUE cmd_major_version_number(void);
  370. DEFUN("major-version-number", cmd_major_version_number, subr_major_version_number, (void), V_Subr0, DOC_major_version_number) /*
  371. ::doc:major_version_number::
  372. (major-version-number)
  373. ::end:: */
  374. {
  375.     static VALUE major_version_number;
  376.     if(!major_version_number)
  377.     {
  378.     major_version_number = newnumber(MAJOR);
  379.     markstatic(&major_version_number);
  380.     }
  381.     return(major_version_number);
  382. }
  383.  
  384. _PR VALUE cmd_minor_version_number(void);
  385. DEFUN("minor-version-number", cmd_minor_version_number, subr_minor_version_number, (void), V_Subr0, DOC_minor_version_number) /*
  386. ::doc:minor_version_number::
  387. (minor-version-number)
  388. ::end:: */
  389. {
  390.     static VALUE minor_version_number;
  391.     if(!minor_version_number)
  392.     {
  393.     minor_version_number = newnumber(MINOR);
  394.     markstatic(&minor_version_number);
  395.     }
  396.     return(minor_version_number);
  397. }
  398.  
  399. _PR VALUE cmd_getenv(VALUE name);
  400. DEFUN("getenv", cmd_getenv, subr_getenv, (VALUE name), V_Subr1, DOC_getenv) /*
  401. ::doc:getenv::
  402. (getenv NAME)
  403. Returns the value of environment variable NAME as a string, or nil if it is
  404. undefined.
  405. ::end:: */
  406. {
  407.     char *val;
  408.     DECLARE1(name, STRINGP);
  409.     val = getenv(VSTR(name));
  410.     if(val)
  411.     return(valstrdup(val));
  412.     return(sym_nil);
  413. }
  414.  
  415. void
  416. misc_init(void)
  417. {
  418.     ADD_SUBR(subr_file_concat);
  419.     ADD_SUBR(subr_system);
  420.     ADD_SUBR(subr_substr);
  421.     ADD_SUBR(subr_beep);
  422.     ADD_SUBR(subr_base_name);
  423.     ADD_SUBR(subr_path_name);
  424.     ADD_SUBR(subr_balance_brackets);
  425.     ADD_SUBR(subr_strtoc);
  426.     ADD_SUBR(subr_ctostr);
  427.     ADD_SUBR(subr_amiga_p);
  428.     ADD_SUBR(subr_x11_p);
  429.     ADD_SUBR(subr_unix_p);
  430.     ADD_SUBR(subr_tmp_file_name);
  431.     ADD_SUBR(subr_make_completion_string);
  432.     ADD_SUBR(subr_current_time);
  433.     ADD_SUBR(subr_current_time_string);
  434.     ADD_SUBR(subr_major_version_number);
  435.     ADD_SUBR(subr_minor_version_number);
  436.     ADD_SUBR(subr_getenv);
  437. }
  438.