Exemplo n.º 1
0
static void
add_sub(int n, const char *string, regex_t *re, regmatch_t *pm)
{
	if (n > (int)re->re_nsub)
		warnx("No subexpression %d", n);
	/* Subexpressions that did not match are
	 * not an error.  */
	else if (pm[n].rm_so != -1 && pm[n].rm_eo != -1)
		addchars(string + pm[n].rm_so, pm[n].rm_eo - pm[n].rm_so);
}
Exemplo n.º 2
0
void
doesyscmd(const char *cmd)
{
	int p[2];
	pid_t pid, cpid;
	char *argv[4];
	int cc;
	int status;

	/* Follow gnu m4 documentation: first flush buffers. */
	fflush(NULL);

	argv[0] = "sh";
	argv[1] = "-c";
	argv[2] = (char *)cmd;
	argv[3] = NULL;

	/* Just set up standard output, share stderr and stdin with m4 */
	if (pipe(p) == -1)
		err(1, "bad pipe");
	switch(cpid = fork()) {
	case -1:
		err(1, "bad fork");
		/* NOTREACHED */
	case 0:
		(void) close(p[0]);
		(void) dup2(p[1], 1);
		(void) close(p[1]);
		execv(_PATH_BSHELL, argv);
		exit(1);
	default:
		/* Read result in two stages, since m4's buffer is
		 * pushback-only. */
		(void) close(p[1]);
		do {
			char result[BUFSIZE];
			cc = read(p[0], result, sizeof result);
			if (cc > 0)
				addchars(result, cc);
		} while (cc > 0 || (cc == -1 && errno == EINTR));

		(void) close(p[0]);
		while ((pid = wait(&status)) != cpid && pid >= 0)
			continue;
		pbstr(getstring());
	}
}
Exemplo n.º 3
0
/* In Gnu m4 mode, parentheses for backmatch don't work like POSIX 1003.2
 * says. So we twiddle with the regexp before passing it to regcomp.
 */
static char *
twiddle(const char *p)
{
	/* + at start of regexp is a normal character for Gnu m4 */
	if (*p == '^') {
		addchar(*p);
		p++;
	}
	if (*p == '+') {
		addchar('\\');
	}
	/* This could use strcspn for speed... */
	while (*p != '\0') {
		if (*p == '\\') {
			switch(p[1]) {
			case '(':
			case ')':
			case '|':
				addchar(p[1]);
				break;
			case 'w':
				addconstantstring("[_a-zA-Z0-9]");
				break;
			case 'W':
				addconstantstring("[^_a-zA-Z0-9]");
				break;
			case '<':
				addconstantstring("[[:<:]]");
				break;
			case '>':
				addconstantstring("[[:>:]]");
				break;
			default:
				addchars(p, 2);
				break;
			}
			p+=2;
			continue;
		}
		if (*p == '(' || *p == ')' || *p == '|')
			addchar('\\');

		addchar(*p);
		p++;
	}
	return getstring();
}
Exemplo n.º 4
0
/* argv[2]: string
 * argv[3]: regexp
 * argv[4]: opt rep
 */
void
dopatsubst(const char *argv[], int argc)
{
	if (argc <= 3) {
		warnx("Too few arguments to patsubst");
		return;
	}
	/* special case: empty regexp */
	if (argv[3][0] == '\0') {
		const char *s;
		size_t len;
		if (argc > 4 && argv[4])
			len = strlen(argv[4]);
		else
			len = 0;
		for (s = argv[2]; *s != '\0'; s++) {
			addchars(argv[4], len);
			addchar(*s);
		}
	} else {
		int error;
		regex_t re;
		regmatch_t *pmatch;
		int mode = REG_EXTENDED;
		const char *source;
		size_t l = strlen(argv[3]);

		if (!mimic_gnu ||
		    (argv[3][0] == '^') ||
		    (l > 0 && argv[3][l-1] == '$'))
			mode |= REG_NEWLINE;

		source = mimic_gnu ? twiddle(argv[3]) : argv[3];
		error = regcomp(&re, source, mode);
		if (error != 0)
			exit_regerror(error, &re, source);

		pmatch = xreallocarray(NULL, re.re_nsub+1, sizeof(regmatch_t), 
		    NULL);
		do_subst(argv[2], &re, source,
		    argc > 4 && argv[4] != NULL ? argv[4] : "", pmatch);
		free(pmatch);
		regfree(&re);
	}
	pbstr(getstring());
}
Exemplo n.º 5
0
static void
do_subst(const char *string, regex_t *re, const char *source, 
    const char *replace, regmatch_t *pm)
{
	int error;
	int flags = 0;
	const char *last_match = NULL;

	while ((error = regexec(re, string, re->re_nsub+1, pm, flags)) == 0) {
		if (pm[0].rm_eo != 0) {
			if (string[pm[0].rm_eo-1] == '\n')
				flags = 0;
			else
				flags = REG_NOTBOL;
		}

		/* NULL length matches are special... We use the `vi-mode'
		 * rule: don't allow a NULL-match at the last match
		 * position.
		 */
		if (pm[0].rm_so == pm[0].rm_eo &&
		    string + pm[0].rm_so == last_match) {
			if (*string == '\0')
				return;
			addchar(*string);
			if (*string++ == '\n')
				flags = 0;
			else
				flags = REG_NOTBOL;
			continue;
		}
		last_match = string + pm[0].rm_so;
		addchars(string, pm[0].rm_so);
		add_replace(string, re, replace, pm);
		string += pm[0].rm_eo;
	}
	if (error != REG_NOMATCH)
		exit_regerror(error, re, source);
	pbstr(string);
}
Exemplo n.º 6
0
void
doformat(const char *argv[], int argc)
{
	const char *format = argv[2];
	int pos = 3;
	int left_padded;
	long width;
	size_t l;
	const char *thisarg;
	char temp[2];
	long extra;

	while (*format != 0) {
		if (*format != '%') {
			addchar(*format++);
			continue;
		}

		format++;
		if (*format == '%') {
			addchar(*format++);
			continue;
		}
		if (*format == 0) {
			addchar('%');
			break;
		}

		if (*format == '*') {
			format++;
			if (pos >= argc)
				m4errx(1,
				    "Format with too many format specifiers.");
			width = strtol(argv[pos++], NULL, 10);
		} else {
			width = strtol(format, (char **)&format, 10);
		}
		if (width < 0) {
			left_padded = 1;
			width = -width;
		} else {
			left_padded = 0;
		}
		if (*format == '.') {
			format++;
			if (*format == '*') {
				format++;
				if (pos >= argc)
					m4errx(1,
					    "Format with too many format specifiers.");
				extra = strtol(argv[pos++], NULL, 10);
			} else {
				extra = strtol(format, (char **)&format, 10);
			}
		} else {
			extra = LONG_MAX;
		}
		if (pos >= argc)
			m4errx(1, "Format with too many format specifiers.");
		switch(*format) {
		case 's':
			thisarg = argv[pos++];
			break;
		case 'c':
			temp[0] = strtoul(argv[pos++], NULL, 10);
			temp[1] = 0;
			thisarg = temp;
			break;
		default:
			m4errx(1, "Unsupported format specification: %s.",
			    argv[2]);
		}
		format++;
		l = strlen(thisarg);
		if (l > extra)
			l = extra;
		if (!left_padded) {
			while (l < width--)
				addchar(' ');
		}
		addchars(thisarg, l);
		if (left_padded) {
			while (l < width--)
				addchar(' ');
		}
	}
	pbstr(getstring());
}
Exemplo n.º 7
0
static void scan_dir(fpick_dd *dt, DIR *dp, char *select)
{
	char full_name[PATHBUF], txt_size[64], txt_date[64], tmp_txt[64];
	char *nm, *src, *dest, *dir = dt->txt_directory;
	memx2 mem = dt->files;
	struct tm *lt;
	struct dirent *ep;
	struct stat buf;
	int *tc;
	int subdir, tf, n, l = strlen(dir), cnt = 0;

	mem.here = 0;
	getmemx2(&mem, 8000); // default size

	dt->idx = -1;
	if (strcmp(dir, DIR_SEP_STR)) // Have a parent dir to move to?
	{
		// Field #0 - original name
		addstr(&mem, "..", 0);
		// Field #1 - type flag (space) + name in GUI encoding
		addstr(&mem, " " DIR_SEP_STR " ..", 0);
		// Fields #2-4 empty for all dirs
		// Fields #5-6 are empty strings, to keep this sorted first
		addchars(&mem, 0, 3 + 2);
		cnt++;
	}

	while ((ep = readdir(dp)))
	{
		wjstrcat(full_name, PATHBUF, dir, l, ep->d_name, NULL);

		// Error getting file details
		if (stat(full_name, &buf) < 0) continue;

		if (!dt->show_hidden && (ep->d_name[0] == '.')) continue;

#ifdef WIN32
		subdir = S_ISDIR(buf.st_mode);
#else
		subdir = (ep->d_type == DT_DIR) || S_ISDIR(buf.st_mode);
#endif
		tf = 'F'; // Type flag: 'D' for dir, 'F' for file
		if (subdir)
		{
			if (!dt->allow_dirs) continue;
			// Don't look at '.' or '..'
			if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
				continue;
			tf = 'D';
		}
		else if (!dt->allow_files) continue;

		/* Remember which row has matching name */
		if (select && !strcmp(ep->d_name, select)) dt->idx = cnt;

		cnt++;

		// Field #0 - original name
		addstr(&mem, ep->d_name, 0);
		// Field #1 - type flag + name in GUI encoding
		addchars(&mem, tf, 1);
		nm = gtkuncpy(NULL, ep->d_name, 0);
		addstr(&mem, nm, 0);
		// Fields #2-4 empty for dirs
		if (subdir) addchars(&mem, 0, 3);
		else
		{
			// Field #2 - file size
#ifdef WIN32
			n = snprintf(tmp_txt, 64, "%I64u", (unsigned long long)buf.st_size);
#else
			n = snprintf(tmp_txt, 64, "%llu", (unsigned long long)buf.st_size);
#endif
			memset(txt_size, ' ', 20);
			dest = txt_size + 20; *dest-- = '\0';
			for (src = tmp_txt + n - 1; src - tmp_txt > 2; )
			{
				*dest-- = *src--;
				*dest-- = *src--;
				*dest-- = *src--;
				*dest-- = ',';
			}
			while (src - tmp_txt >= 0) *dest-- = *src--;
			addstr(&mem, txt_size, 0);
			// Field #3 - file type (extension)
			src = strrchr(nm, '.');
			if (src && (src != nm) && src[1])
			{
#if GTK_MAJOR_VERSION == 1
				g_strup(src = g_strdup(src + 1));
#else
				src = g_utf8_strup(src + 1, -1);
#endif
				addstr(&mem, src, 0);
				g_free(src);
			}
			else addchars(&mem, 0, 1);
			// Field #4 - file modification time
			strcpy(txt_date, " "); // to sort failed files after dirs
			lt = localtime(&buf.st_mtime);
			/* !!! localtime() can fail and return NULL if given
			 * "wrong" input value */
			if (lt) strftime(txt_date, 60, "%Y-%m-%d   %H:%M.%S", lt);
			addstr(&mem, txt_date, 0);
		}
		// Field #5 - case-insensitive sort key
		src = isort_key(nm);
		addstr(&mem, src, 0);
		g_free(src);
		// Field #6 - alphabetic (case-sensitive) sort key
#if GTK_MAJOR_VERSION == 1
		addstr(&mem, nm, 0);
#else /* if GTK_MAJOR_VERSION == 2 */
		src = g_utf8_collate_key(nm, -1);
		addstr(&mem, src, 0);
		g_free(src);
#endif
		g_free(nm);
	}
	dt->cnt = cnt;

	/* Now add index array and mapping arrays to all this */
	l = (~(unsigned)mem.here + 1) & (sizeof(int) - 1);
	n = cnt * COL_MAX;
	getmemx2(&mem, l + (n + cnt) * sizeof(int));
	// Fill index array
	tc = dt->fcols = (void *)(mem.buf + mem.here + l);
	src = mem.buf;
	while (n-- > 0)
	{
		*tc = src - (char *)tc;
		tc++;
		src += strlen(src) + 1;
	}
	// Setup mapping array
	dt->fmap = tc;

	dt->files = mem;
}
Exemplo n.º 8
0
void PrintInteger(bool typeUnsigned, uint64_t argu, int base, uint64_t numbits,
                  FormatterParams formatter, bool uppercaseDigits, char *&output,
                  size_t &actualsize, char *end)
{
  int64_t argi = 0;

  union
  {
    uint64_t *u64;
    signed int *i;
    signed char *c;
    signed short *s;
    int64_t *i64;
  } typepun;

  typepun.u64 = &argu;

  // cast the appropriate size to signed version
  switch(formatter.Length)
  {
    default:
    case None:
    case Long: argi = (int64_t)*typepun.i; break;
    case HalfHalf: argi = (int64_t)*typepun.c; break;
    case Half: argi = (int64_t)*typepun.s; break;
    case LongLong: argi = (int64_t)*typepun.i64; break;
  }

  bool negative = false;
  if(base == 10 && !typeUnsigned)
  {
    negative = argi < 0;
  }

  int digwidth = 0;
  int numPad0s = 0;
  int numPadWidth = 0;
  {
    int intwidth = 0;
    int digits = 0;

    // work out the number of decimal digits in the integer
    if(!negative)
    {
      uint64_t accum = argu;
      while(accum)
      {
        digits += 1;
        accum /= base;
      }
    }
    else
    {
      int64_t accum = argi;
      while(accum)
      {
        digits += 1;
        accum /= base;
      }
    }

    intwidth = digwidth = RDCMAX(1, digits);

    // printed int is 2 chars larger for 0x or 0b, and 1 char for 0 (octal)
    if(base == 16 || base == 2)
      intwidth += formatter.Flags & AlternateForm ? 2 : 0;
    if(base == 8)
      intwidth += formatter.Flags & AlternateForm ? 1 : 0;

    if(formatter.Precision != FormatterParams::NoPrecision && formatter.Precision > intwidth)
      numPad0s = formatter.Precision - intwidth;

    intwidth += numPad0s;

    // for decimal we can have a negative sign (or placeholder)
    if(base == 10)
    {
      if(negative)
        intwidth++;
      else if(formatter.Flags & (PrependPos | PrependSpace))
        intwidth++;
    }

    if(formatter.Width != FormatterParams::NoWidth && formatter.Width > intwidth)
      numPadWidth = formatter.Width - intwidth;
  }

  // pad with spaces if necessary
  if((formatter.Flags & (LeftJustify | PadZeroes)) == 0 && numPadWidth > 0)
    addchars(output, actualsize, end, (size_t)numPadWidth, ' ');

  if(base == 16)
  {
    if(formatter.Flags & AlternateForm)
    {
      if(uppercaseDigits)
        appendstring(output, actualsize, end, "0X");
      else
        appendstring(output, actualsize, end, "0x");
    }

    // pad with 0s as appropriate
    if((formatter.Flags & (LeftJustify | PadZeroes)) == PadZeroes && numPadWidth > 0)
      addchars(output, actualsize, end, (size_t)numPadWidth, '0');
    if(numPad0s > 0)
      addchars(output, actualsize, end, (size_t)numPad0s, '0');

    bool left0s = true;

    // mask off each hex digit and print
    for(uint64_t i = 0; i < numbits; i += 4)
    {
      uint64_t shift = numbits - 4 - i;
      uint64_t mask = 0xfULL << shift;
      char digit = char((argu & mask) >> shift);
      if(digit == 0 && left0s && i + 4 < numbits)
        continue;
      left0s = false;

      if(digit < 10)
        addchar(output, actualsize, end, '0' + digit);
      else if(uppercaseDigits)
        addchar(output, actualsize, end, 'A' + digit - 10);
      else
        addchar(output, actualsize, end, 'a' + digit - 10);
    }
  }
  else if(base == 8)