Example #1
0
File: bog.c Project: berkus/lang-e
/* mkvar: adds s to the list l of the current pattern's variables */
List mkvar (Symbol s, List l) {
     var_t *var;

     if (debugp) 
	  fprintf(stderr, "/* mkvar: %s [l=%d,r=%d] */\n", s->name, s->l, s->r);
     foreach(stab, checksame, s, 0);

     NEW(var, 1, ARENA0);
     var->id = s->name[0]-'a';
     var->sh = SZ-1-s->r;
     var->msk = ((2 << (s->r - s->l)) - 1) << var->sh;
     return l_append((void *)var, l, ARENA0);
}
Example #2
0
/* concatenate list src with list dst */
int l_concat(list_t *dst, list_t **src)
{
    void *data;
    element_t *n;

    n = (*src)->head;
    
    while (n) {
        l_remove(*src, NULL, &data);
        if (l_append(dst, NULL, data) == -1)
            return -1;
        
        n = (*src)->head;
    }
    
    l_destroy(*src);
    
    *src = NULL;
    
    return 0;
}
Example #3
0
static int add_section_label(struct label *l, const char *name,
			     const char *attribute, uint64_t value,
			     struct label **length)
{
	char label[255];
	int errcode;

	errcode = create_section_label_name(label, sizeof(label), name,
					    attribute);
	if (errcode < 0)
		return errcode;

	errcode = l_append(l, label, value);
	if (errcode < 0)
		return errcode;

	if (length)
		*length = l_find(l, label);

	return 0;
}
Example #4
0
/*lint -esym(818,handler) dont declare handler const */
bool registercommand(const char *command, void *handler, list_t * commands,
                     char *shortdoc, char *longdoc)
{
    command_t *data;

    assert(commands != NULL);

    if (command != NULL) {
        if ((data = malloc(sizeof(command_t) + strlen(command) + 1)) == NULL) {
            show_error("sorry, there was a memory allocation problem.\n");
            return false;
        }
        data->command = (char *) data + sizeof(*data);

        /* command points to the extra space allocated after data */
        strcpy(data->command, command);
    } else {
        if ((data = malloc(sizeof(command_t))) == NULL) {
            show_error("sorry, there was a memory allocation problem.\n");
            return false;
        }
        data->command = NULL;
    }

    data->handler = handler;
    data->shortdoc = shortdoc;
    data->longdoc = longdoc;

    /* add new command to list */
    if (l_append(commands, NULL, data) == -1) {
        free(data);
        return false;
    }

    return true;
}
Example #5
0
int parse_yasm_labels(struct label *l, const struct text *t)
{
	int errcode, no_org_directive;
	size_t i;
	uint64_t base_addr;
	enum { linelen = 1024 };
	char line[linelen];

	if (bug_on(!t))
		return -err_internal;

	base_addr = 0;
	no_org_directive = 1;

	/* determine base address from org directive, error out on
	 * sections.
	 */
	for (i = 0; i < t->n; i++) {
		char *tmp;

		errcode = text_line(t, line, linelen, i);
		if (errcode < 0)
			return errcode;

		tmp = strstr(line, "[section");
		if (tmp)
			return -err_section;

		tmp = strstr(line, "[org");
		if (!tmp)
			continue;

		base_addr = strtol(tmp+strlen("[org"), NULL, 0);
		no_org_directive = 0;
		break;
	}

	if (no_org_directive)
		return -err_no_org_directive;

	for (i = 0; i < t->n; i++) {
		char *tmp, *name;
		uint64_t addr;

		errcode = text_line(t, line, linelen, i);
		if (errcode < 0)
			goto error;

		/* skip line number count.  */
		tmp = strtok(line, " ");
		if (!tmp)
			continue;

		/* the label can now be on the same line as the memory
		 * address or on a line by its own.
		 * we look at the next token and (1) if it looks like a
		 * label, we search in the following lines for the
		 * corresponding address; or (2) if it looks like an
		 * address, we store it and see if the token after the
		 * opcode looks like a token; or (3) none of the above,
		 * we continue with the next line.
		 */

		/* second token after the line number count.  it's
		 * either an address; or a label.
		 */
		tmp = strtok(NULL, " ");
		if (!tmp)
			continue;

		if (!make_label(tmp)) {
			/* get address in case we find a label later.  */
			if (sscanf(tmp, "%" PRIx64, &addr) != 1)
				continue;

			/* skip the opcode token.  */
			tmp = strtok(NULL, " ");
			if (!tmp)
				continue;

			/* this might be a label now.  */
			tmp = strtok(NULL, " ");
			if (!make_label(tmp))
				continue;

			errcode = l_append(l, tmp, addr + base_addr);
			if (errcode < 0)
				goto error;
			continue;
		}
		name = duplicate_str(tmp);
		if (!name) {
			errcode = -err_no_mem;
			goto error;
		}

		/* there was a label so now an address needs to
		 * be found.
		 */
		errcode = -err_label_addr;
		for (i += 1; i < t->n; i++) {
			int errcode_text;

			errcode_text = text_line(t, line, linelen, i);
			if (errcode_text < 0) {
				errcode = errcode_text;
				break;
			}
			if (sscanf(line, "%*d %" PRIx64 " %*x %*s", &addr)
			    == 1) {
				errcode = l_append(l, name, addr + base_addr);
				break;
			}
		}
		if (errcode == -err_label_addr)
			fprintf(stderr, "label '%s' has no address\n", name);
		free(name);
		if (errcode < 0)
			goto error;
	}

	return 0;

error:
	l_free(l->next);
	free(l->name);
	l->next = NULL;
	l->name = NULL;
	return errcode;
}
Example #6
0
File: bog.c Project: berkus/lang-e
/* scan: parse the contents of fp, expecting the input side (phase) of a rule
   if ph=='i', or the output side if ph=='o' */
List scan (FILE *fp, int ph) {
     int c = 0;			/* Current char on fp */
     int nb = 0, nw = 0;	/* Position in rule (bit/word) */
     Symbol csym = 0L;		/* Current variable being scanned */
     T f_msk=(T)0, f_val=(T)0;	/* Current constant mask and value */
     List pats = 0L;		/* All the patterns (words) for this phase */
     List vars = 0L;		/* All the vars for a given pattern */

     while ((c=getc(fp)) != EOF) {
	  if (debugp)
	       fprintf(stdout, "/* bit: %c msk: 0x%x val: 0x%x */\n", 
		       c, (unsigned)f_msk, (unsigned)f_val);
				/* Inputs end with '=', outputs with '+' */
	  if ((c == '=' && ph == 'i') || (c == '+' && ph == 'o'))
	       break;
	  switch(c) {
	  case ' ': case '\f': case '\n': case '\r': case '\t': case '\v': 
	       continue;
	  case '#':		/* Comment character */
	       while ((c=getc(fp)) != EOF && c != '\n');
	       if (c == EOF && (nb > 0 || (ph == 'i' && nw > 0)))
		    error(stringf("Unexpected end of file reading patterns at "
				  "rule %d, word %c%d, bit %d", nr,ph,nw,nb));
	       continue;
	  case '-':		/* Denotes body of a variable */
	       if (!csym)	/* We must be defining a variable */
		    error(stringf("'-' appears with no leading symbol "
			 "at rule %d, word %c%d, bit %d", nr, ph, nw, nb));
	       else {		/* Extend the variable's right boundary */
		    ++csym->r; assert(csym->r == nb);
	       }
	       break;
	  case '0': case '1':	/* Constant characters */
	       if (csym) {	/* End any variable definition */
		    vars = mkvar(csym, vars); csym = 0L;
	       }
	       f_msk |= 1; f_val |= (c-'0');
	       break;
	  default:
	       c = tolower(c);	/* Variables named by a-z, case insensitive */
	       if (c >= 'a' && c <= 'z') {
		    char *s = stringf("%c", c);
		    if (csym)
			 vars = mkvar(csym, vars);
		    if (!lookup(s, stab) && ph == 'o')
			 error(stringf("Symbol '%c' used with no prior "
				       "definition at rule %d, word o%d",
				       c, nr, nw));
		    csym = install(s, stab);
		    csym->l = csym->r = nb;
	       } else
		    error(stringf("Illegal character in rule file at rule %d, "
				  "word %c%d, bit %d", nr, ph, nw, nb));
	  }
	  if (nb == SZ-1) {	/* End of a pattern (word): append this info */
	       pat_t *pat;	/*  to list of patterns, and reset current */
	       if (csym) {	/*  pattern state (masks, vars, bit count) */
		    vars = mkvar(csym, vars); csym = 0L;
	       }
	       NEW(pat, 1, ARENA0);
	       pat->f_msk = f_msk; f_msk = (T)0;
	       pat->f_val = f_val; f_val = (T)0;
	       pat->nv = l_length(vars);
	       if (debugp)
		    fprintf(stdout, "/* msk: 0x%x, val: 0x%x, nv: 0x%x */\n",
			    (unsigned)pat->f_msk, (unsigned)pat->f_val, 
			    pat->nv);
	       l_ltov(pat->v, var_t *, vars, ARENA0);

	       pats = l_append(pat, pats, ARENA0);
	       ++nw; nb = 0; vars = 0L;
	  } else {		/* Still more to go: move on to next bit */
	       ++nb; f_msk <<= 1; f_val <<= 1;
Example #7
0
/* Processes the current directive.
 * If the encoder returns an error, a message including current file and
 * line number together with the pt error string is printed on stderr.
 *
 * Returns 0 on success; a negative enum errcode otherwise.
 * Returns -err_internal if @p or @e is the NULL pointer.
 * Returns -err_parse_missing_directive if there was a pt directive marker,
 * but no directive.
 * Returns -stop_process if the .exp directive was encountered.
 * Returns -err_pt_lib if the pt encoder returned an error.
 * Returns -err_parse if a general parsing error was encountered.
 * Returns -err_parse_unknown_directive if there was an unknown pt directive.
 */
static int p_process(struct parser *p, struct pt_encoder *e)
{
	int bytes_written;
	int errcode;
	char *directive, *payload, *pt_label_name, *tmp;
	struct pt_directive *pd;
	struct pt_packet packet;

	if (bug_on(!p))
		return -err_internal;

	if (bug_on(!e))
		return -err_internal;

	pd = p->pd;
	if (!pd)
		return -err_internal;

	directive = pd->name;
	payload = pd->payload;

	pt_label_name = NULL;
	bytes_written = 0;
	errcode = 0;

	/* find a label name.  */
	tmp = strchr(directive, ':');
	if (tmp) {
		uint64_t x;

		pt_label_name = directive;
		directive = tmp+1;
		*tmp = '\0';

		/* ignore whitespace between label and directive. */
		while (isspace(*directive))
			directive += 1;

		/* if we can lookup a yasm label with the same name, the
		 * current pt directive label is invalid.  */
		errcode = yasm_lookup_label(p->y, &x, pt_label_name);
		if (errcode == 0)
			errcode = -err_label_not_unique;

		if (errcode != -err_no_label)
			return yasm_print_err(p->y, "label lookup",
					      errcode);

		/* if we can lookup a pt directive label with the same
		 * name, the current pt directive label is invalid.  */
		errcode = l_lookup(p->pt_labels, &x, pt_label_name);
		if (errcode == 0)
			errcode = -err_label_not_unique;

		if (errcode != -err_no_label)
			return yasm_print_err(p->y, "label lookup",
					      -err_label_not_unique);
	}

	/* now try to match the directive string and call the
	 * corresponding function that parses the payload and emits an
	 * according packet.
	 */
	if (strcmp(directive, "") == 0)
		return yasm_print_err(p->y, "invalid syntax",
				      -err_parse_missing_directive);
	else if (strcmp(directive, ".exp") == 0) {
		/* this is the end of processing pt directives, so we
		 * add a p_last label to the pt directive labels.
		 */
		errcode = l_append(p->pt_labels, "eos", p->pt_bytes_written);
		if (errcode < 0)
			return yasm_print_err(p->y, "append label", errcode);

		return -stop_process;
	}

	if (strcmp(directive, "psb") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "psb: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_psb;
	} else if (strcmp(directive, "psbend") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "psbend: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_psbend;
	} else if (strcmp(directive, "pad") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "pad: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_pad;
	} else if (strcmp(directive, "ovf") == 0) {
		errcode = parse_empty(payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "ovf: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_ovf;
	} else if (strcmp(directive, "tnt") == 0) {
		errcode = parse_tnt(&packet.payload.tnt.payload,
				    &packet.payload.tnt.bit_size, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tnt: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tnt_8;
	} else if (strcmp(directive, "tnt64") == 0) {
		errcode = parse_tnt(&packet.payload.tnt.payload,
				    &packet.payload.tnt.bit_size, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tnt64: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tnt_64;
	} else if (strcmp(directive, "tip") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tip: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tip;
	} else if (strcmp(directive, "tip.pge") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tip.pge: parsing failed",
				       errcode);
			goto error;
		}
		packet.type = ppt_tip_pge;
	} else if (strcmp(directive, "tip.pgd") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tip.pgd: parsing failed",
				       errcode);
			goto error;
		}
		packet.type = ppt_tip_pgd;
	} else if (strcmp(directive, "fup") == 0) {
		errcode = parse_ip(p, &packet.payload.ip.ip,
				   &packet.payload.ip.ipc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "fup: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_fup;
	} else if (strcmp(directive, "mode.exec") == 0) {
		if (strcmp(payload, "16bit") == 0) {
			packet.payload.mode.bits.exec.csl = 0;
			packet.payload.mode.bits.exec.csd = 0;
		} else if (strcmp(payload, "64bit") == 0) {
			packet.payload.mode.bits.exec.csl = 1;
			packet.payload.mode.bits.exec.csd = 0;
		} else if (strcmp(payload, "32bit") == 0) {
			packet.payload.mode.bits.exec.csl = 0;
			packet.payload.mode.bits.exec.csd = 1;
		} else {
			errcode = yasm_print_err(p->y,
						 "mode.exec: argument must be one of \"16bit\", \"64bit\" or \"32bit\"",
						 -err_parse);
			goto error;
		}
		packet.payload.mode.leaf = pt_mol_exec;
		packet.type = ppt_mode;
	} else if (strcmp(directive, "mode.tsx") == 0) {
		if (strcmp(payload, "begin") == 0) {
			packet.payload.mode.bits.tsx.intx = 1;
			packet.payload.mode.bits.tsx.abrt = 0;
		} else if (strcmp(payload, "abort") == 0) {
			packet.payload.mode.bits.tsx.intx = 0;
			packet.payload.mode.bits.tsx.abrt = 1;
		} else if (strcmp(payload, "commit") == 0) {
			packet.payload.mode.bits.tsx.intx = 0;
			packet.payload.mode.bits.tsx.abrt = 0;
		} else {
			errcode = yasm_print_err(p->y,
						 "mode.tsx: argument must be one of \"begin\", \"abort\" or \"commit\"",
						 -err_parse);
			goto error;
		}
		packet.payload.mode.leaf = pt_mol_tsx;
		packet.type = ppt_mode;
	} else if (strcmp(directive, "pip") == 0) {
		errcode = parse_uint64(&packet.payload.pip.cr3, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "pip: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_pip;
	} else if (strcmp(directive, "tsc") == 0) {
		errcode = parse_uint64(&packet.payload.tsc.tsc, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "tsc: parsing failed", errcode);
			goto error;
		}
		packet.type = ppt_tsc;
	} else if (strcmp(directive, "cbr") == 0) {
		errcode = parse_uint8(&packet.payload.cbr.ratio, payload);
		if (errcode < 0) {
			yasm_print_err(p->y, "cbr: parsing cbr failed",
				       errcode);
			goto error;
		}
		packet.type = ppt_cbr;
	} else {
		errcode = yasm_print_err(p->y, "invalid syntax",
					 -err_parse_unknown_directive);
		goto error;
	}

	bytes_written = pt_enc_next(e, &packet);
	if (bytes_written < 0) {
		const char *errstr, *format;
		char *msg;
		size_t n;

		errstr = pt_errstr(pt_errcode(bytes_written));
		format = "encoder error in directive %s (status %s)";
		/* the length of format includes the "%s" (-2)
		 * characters, we add errstr (+-0) and then we need
		 * space for a terminating null-byte (+1).
		 */
		n = strlen(format)-4 + strlen(directive) + strlen(errstr) + 1;

		msg = malloc(n);
		if (!msg)
			errcode = yasm_print_err(p->y,
				       "encoder error not enough memory to show error code",
				       -err_pt_lib);
		else {
			sprintf(msg, format, directive, errstr);
			errcode = yasm_print_err(p->y, msg, -err_pt_lib);
			free(msg);
		}
	} else {
		if (pt_label_name) {
			errcode = l_append(p->pt_labels, pt_label_name,
					   p->pt_bytes_written);
			if (errcode < 0)
				goto error;
		}
		p->pt_bytes_written += bytes_written;
	}

error:
	if (errcode < 0)
		bytes_written = errcode;
	return bytes_written;
}
Example #8
0
int parse_yasm_labels(struct label *l, const struct text *t)
{
	int errcode, no_org_directive;
	size_t i;
	uint64_t base_addr;
	enum { linelen = 1024 };
	char line[linelen];
	struct label *length;

	if (bug_on(!t))
		return -err_internal;

	base_addr = 0;
	no_org_directive = 1;
	length = NULL;

	/* determine base address from org directive and insert special
	 * section labels.
	 */
	for (i = 0; i < t->n; i++) {
		char *tmp;

		errcode = text_line(t, line, linelen, i);
		if (errcode < 0)
			return errcode;

		tmp = strstr(line, "[section");
		if (tmp) {
			tmp += strlen("[section");
			errcode = parse_section(tmp, l, &length);
			if (errcode < 0)
				return errcode;
			continue;
		}

		tmp = strstr(line, "[org");
		if (tmp) {
			base_addr = strtol(tmp+strlen("[org"), NULL, 0);

			errcode = l_append(l, "org", base_addr);
			if (errcode < 0)
				return errcode;

			no_org_directive = 0;
			continue;
		}

		/* update the section_<name>_length label, if we have one.
		 *
		 * this must be last; it destroys @line.
		 */
		if (length) {
			uint64_t value, size;

			tmp = strtok(line, " ");
			if (!tmp)
				continue;

			/* we expect a line number. */
			errcode = str_to_uint64(tmp, &value, 10);
			if (errcode < 0)
				continue;

			tmp = strtok(NULL, " ");
			if (!tmp)
				continue;

			/* we expect an address. */
			errcode = str_to_uint64(tmp, &value, 16);
			if (errcode < 0)
				continue;

			tmp = strtok(NULL, " ");
			if (!tmp)
				continue;

			/* we expect an opcode. */
			errcode = str_to_uint64(tmp, &value, 16);
			if (errcode < 0)
				continue;

			/* we got an opcode - let's compute it's size. */
			for (size = 0; value != 0; value >>= 8)
				size += 1;

			/* update the section_<name>_length label. */
			length->addr += size;
		}
	}

	if (no_org_directive)
		return -err_no_org_directive;

	for (i = 0; i < t->n; i++) {
		char *tmp, *name;
		uint64_t addr;

		errcode = text_line(t, line, linelen, i);
		if (errcode < 0)
			goto error;

		/* Change the base on section switches. */
		tmp = strstr(line, "[section");
		if (tmp) {
			tmp += strlen("[section");
			errcode = lookup_section_vstart(l, tmp, &base_addr);
			if (errcode < 0)
				return errcode;
			continue;
		}

		/* skip line number count.  */
		tmp = strtok(line, " ");
		if (!tmp)
			continue;

		/* the label can now be on the same line as the memory
		 * address or on a line by its own.
		 * we look at the next token and (1) if it looks like a
		 * label, we search in the following lines for the
		 * corresponding address; or (2) if it looks like an
		 * address, we store it and see if the token after the
		 * opcode looks like a token; or (3) none of the above,
		 * we continue with the next line.
		 */

		/* second token after the line number count.  it's
		 * either an address; or a label.
		 */
		tmp = strtok(NULL, " ");
		if (!tmp)
			continue;

		if (!make_label(tmp)) {
			/* get address in case we find a label later.  */
			if (sscanf(tmp, "%" PRIx64, &addr) != 1)
				continue;

			/* skip the opcode token.  */
			tmp = strtok(NULL, " ");
			if (!tmp)
				continue;

			/* this might be a label now.  */
			tmp = strtok(NULL, " ");
			if (!make_label(tmp))
				continue;

			errcode = l_append(l, tmp, addr + base_addr);
			if (errcode < 0)
				goto error;
			continue;
		}
		name = duplicate_str(tmp);
		if (!name) {
			errcode = -err_no_mem;
			goto error;
		}

		/* there was a label so now an address needs to
		 * be found.
		 */
		errcode = -err_label_addr;
		for (i += 1; i < t->n; i++) {
			int errcode_text;

			errcode_text = text_line(t, line, linelen, i);
			if (errcode_text < 0) {
				errcode = errcode_text;
				break;
			}
			if (sscanf(line, "%*d %" PRIx64 " %*x %*s", &addr)
			    == 1) {
				errcode = l_append(l, name, addr + base_addr);
				break;
			}
		}
		if (errcode == -err_label_addr)
			fprintf(stderr, "label '%s' has no address\n", name);
		free(name);
		if (errcode < 0)
			goto error;
	}

	return 0;

error:
	l_free(l->next);
	free(l->name);
	l->next = NULL;
	l->name = NULL;
	return errcode;
}
Example #9
0
File: tog.c Project: berkus/lang-e
/* convert: read the text rewrite rules on fp, generating bog rewrite rules (on
   fr) and C tables (on ft) for use with tpo */
static void convert (FILE *fp, FILE *fr, FILE *ft) {
     int phase = IN, lc = 0, id, vused[26], i;
     char c, l[LSZ], *lp, v[VSZ], *vp;
     List trul = 0, tlin = 0, brul = 0, blin = 0, patterns = 0;

     for (i = 0; i < 26; i++) vused[i] = 0;
     while (fgets(l, LSZ, fp)) {
	  ++lc;
	  if (*l == '#' || *l == '\n') continue;
	  if (!strcmp(l, "=\n")) { /* End of input pattern */
	       if (phase != IN)
		    error(stringf("Misplaced '=' at line %d", lc));
	       if (!blin)
		    warning(stringf("Empty input pattern at line %d", lc));
	       trul = l_append((void *)tlin, trul, ARENA0); tlin = 0;
	       brul = l_append((void *)blin, brul, ARENA0); blin = 0;
	       phase = OUT;
	       continue;
	  }
	  if (!strcmp(l, "+\n")) { /* End of output pattern */
	       if (phase != OUT)
		    error(stringf("Misplaced '+' at line %d", lc));
	       brul = l_append((void *)blin, brul, ARENA0); blin = 0;
	       for (i = 0; i < 26; i++) vused[i] = 0;
	       phase = IN;
	       continue;
	  }
				/* Extend text line list */
	  for (lp = l; *lp; lp++) ; if (*--lp == '\n') *lp = '\0';
	  if (phase == IN)
	       tlin = l_append((void*)string(l), tlin, ARENA0);

	  vp = v;		/* "Uniqueify" string */
	  for (lp = l; *lp; lp++)
	       if (*lp == '%')
		    if ((c = tolower(*++lp)) >= 'a' && c <= 'z') {
			 int j = c-'a';
			 *vp++ = c; *lp = ' ';
			 if (phase == IN)
			      vused[j] = 1;
			 else if (!vused[j])
			      error(stringf("Symbol '%%%c' used with no prior "
					    "definition at line %d", c, lc));
		    } else if (c != '%')
			 error(stringf("Illegal expression '%%%c' at line %d",
				       c, lc));
	  *vp++ = 0;
				/* Extend list of uniq'd patterns */
	  if (uniq(l, &lp, &id))
	       patterns = l_append((void *)lp, patterns, ARENA0);
	  PDEBUG(("convert: %s :: %d\n", lp, id));
				/* Extend binary line list (for bog) */
	  blin = l_append((void *)id, blin, ARENA0);
	  blin = l_append((void *)string(v), blin, ARENA0);
     }

     unparsebin(brul, fr);
     fprintf(ft, "#include \"tpo.h\"\n\n");
     unparsepat(patterns, ft);
     unparsetxt(trul, ft);
}
Example #10
0
/* dregion [!][x][,x,...] */
bool handler__dregion(globals_t * vars, char **argv, unsigned argc)
{
    unsigned id;
    bool invert = false;
    char *end = NULL, *idstr = NULL, *block = NULL;
    element_t *np, *pp;
    list_t *keep = NULL;
    region_t *save;

    /* need an argument */
    if (argc < 2) {
        show_error("expected an argument, see `help dregion`.\n");
        return false;
    }

     /* check that there is a process known */
    if (vars->target == 0) {
        show_error("no target specified, see `help pid`\n");
        return false;
    }
    
    /* check for an inverted match */
    if (*argv[1] == '!') {
        invert = true;
        /* create a copy of the argument for strtok(), +1 to skip '!' */
        block = strdupa(argv[1] + 1);
        
        /* check for lone '!' */
        if (*block == '\0') {
            show_error("inverting an empty set, maybe try `reset` instead?\n");
            return false;
        }
        
        /* create a list to keep the specified regions */
        if ((keep = l_init()) == NULL) {
            show_error("memory allocation error.\n");
            return false;
        }
        
    } else {
        invert = false;
        block = strdupa(argv[1]);
    }

    /* loop for every number specified, eg "1,2,3,4,5" */
    while ((idstr = strtok(block, ",")) != NULL) {
        region_t *r = NULL;
        
        /* set block to NULL for strtok() */
        block = NULL;
        
        /* attempt to parse as a regionid */
        id = strtoul(idstr, &end, 0x00);

        /* check that worked, "1,abc,4,,5,6foo" */
        if (*end != '\0' || *idstr == '\0') {
            show_error("could not parse argument %s.\n", idstr);
            if (invert) {
                if (l_concat(vars->regions, &keep) == -1) {
                    show_error("there was a problem restoring saved regions.\n");
                    l_destroy(vars->regions);
                    l_destroy(keep);
                    return false;
                }
            }
            assert(keep == NULL);
            return false;
        }
        
        /* initialise list pointers */
        np = vars->regions->head;
        pp = NULL;
        
        /* find the correct region node */
        while (np) {
            r = np->data;
            
            /* compare the node id to the id the user specified */
            if (r->id == id)
                break;
            
            pp = np; /* keep track of prev for l_remove() */
            np = np->next;
        }

        /* check if a match was found */
        if (np == NULL) {
            show_error("no region matching %u, or already moved.\n", id);
            if (invert) {
                if (l_concat(vars->regions, &keep) == -1) {
                    show_error("there was a problem restoring saved regions.\n");
                    l_destroy(vars->regions);
                    l_destroy(keep);
                    return false;
                }
            }
            if (keep)
                l_destroy(keep);
            return false;
        }
        
        np = pp;
        
        /* save this region if the match is inverted */
        if (invert) {
            
            assert(keep != NULL);
            
            l_remove(vars->regions, np, (void *) &save);
            if (l_append(keep, keep->tail, save) == -1) {
                show_error("sorry, there was an internal memory error.\n");
                free(save);
                return false;
            }
            continue;
        }
        
        /* check for any affected matches before removing it */
        if(vars->num_matches > 0)
        {
            region_t *s;

            /* determine the correct pointer we're supposed to be checking */
            if (np) {
                assert(np->next);
                s = np->next->data;
            } else {
                /* head of list */
                s = vars->regions->head->data;
            }
            
            if (!(vars->matches = delete_by_region(vars->matches, &vars->num_matches, s, false)))
            {
                show_error("memory allocation error while deleting matches\n");
            }
        }

        l_remove(vars->regions, np, NULL);
    }

    if (invert) {
        region_t *s = keep->head->data;
        
        if (vars->num_matches > 0)
        {
            if (!(vars->matches = delete_by_region(vars->matches, &vars->num_matches, s, true)))
            {
                show_error("memory allocation error while deleting matches\n");
            }
        }
            
        /* okay, done with the regions list */
        l_destroy(vars->regions);
        
        /* and switch to the keep list */
        vars->regions = keep;
    }

    return true;
}