rc

[fork] interactive rc shell
git clone https://hhvn.uk/rc
git clone git://hhvn.uk/rc
Log | Files | Refs | README | LICENSE

utils.c (1739B)


      1 /* utils.c: functions of general utility */
      2 
      3 #include "rc.h"
      4 
      5 #include <errno.h>
      6 #include <setjmp.h>
      7 
      8 #include "jbwrap.h"
      9 
     10 /* print error with line number on noninteractive shells (i.e., scripts) */
     11 
     12 extern void pr_error(char *s, int offset) {
     13 	if (s != NULL) {
     14 		if (interactive)
     15 			fprint(2, RC "%s\n", s);
     16 		else
     17 			fprint(2, RC "line %d: %s\n", lineno + offset, s);
     18 	}
     19 }
     20 
     21 /* our perror */
     22 
     23 extern void uerror(char *s) {
     24 	char *err;
     25 
     26 	err = strerror(errno);
     27 	if (!err) err = "unknown error";
     28 
     29 	if (s)
     30 		fprint(2, RC "%s: %s\n", s, err);
     31 	else
     32 		fprint(2, RC "%s\n", err);
     33 }
     34 
     35 /* Die horribly. This should never get called. Please let me know if it does. */
     36 
     37 #define PANICMSG "rc panic: "
     38 
     39 extern void panic(char *s) {
     40 	write(2, PANICMSG, conststrlen(PANICMSG));
     41 	write(2, s, strlen(s));
     42 	write(2, "!\n", 2);
     43 	exit(1);
     44 }
     45 
     46 /* ascii -> unsigned conversion routines. -1 indicates conversion error. */
     47 
     48 extern int n2u(char *s, unsigned int base) {
     49 	unsigned int i;
     50 	for (i = 0; *s != '\0'; s++) {
     51 		unsigned int j = (unsigned int) *s - '0';
     52 		if (j >= base) /* small hack with unsigned ints -- one compare for range test */
     53 			return -1;
     54 		i = i * base + j;
     55 	}
     56 	return (int) i;
     57 }
     58 
     59 /* The last word in portable ANSI: a strcmp wrapper for qsort */
     60 
     61 extern int starstrcmp(const void *s1, const void *s2) {
     62 	return strcmp(*(char * const *)s1, *(char * const *)s2);
     63 }
     64 
     65 /* tests to see if pathname begins with "/", "./", or "../" */
     66 
     67 extern bool isabsolute(char *path) {
     68 	return path[0] == '/' || (path[0] == '.' && (path[1] == '/' || (path[1] == '.' && path[2] == '/')));
     69 }
     70 
     71 
     72 /* duplicate a fd and close the old one only if necessary */
     73 
     74 extern int mvfd(int i, int j) {
     75 	if (i != j) {
     76 		int s = dup2(i, j);
     77 		close(i);
     78 		return s;
     79 	}
     80 	return 0;
     81 }