示例#1
0
int
cmdline_complete(struct cmdline *cl, const char *buf, int *state,
		 char *dst, unsigned int size)
{
	const char *partial_tok = buf;
	unsigned int inst_num = 0;
	cmdline_parse_inst_t *inst;
	cmdline_parse_token_hdr_t *token_p;
	struct cmdline_token_hdr token_hdr;
	char tmpbuf[CMDLINE_BUFFER_SIZE], comp_buf[CMDLINE_BUFFER_SIZE];
	unsigned int partial_tok_len;
	int comp_len = -1;
	int tmp_len = -1;
	int nb_token = 0;
	unsigned int i, n;
	int l;
	unsigned int nb_completable;
	unsigned int nb_non_completable;
	int local_state = 0;
	const char *help_str;
	cmdline_parse_ctx_t *ctx;

	if (!cl || !buf || !state || !dst)
		return -1;

	ctx = cl->ctx;

	debug_printf("%s called\n", __func__);
	memset(&token_hdr, 0, sizeof(token_hdr));

	/* count the number of complete token to parse */
	for (i=0 ; buf[i] ; i++) {
		if (!isblank2(buf[i]) && isblank2(buf[i+1]))
			nb_token++;
		if (isblank2(buf[i]) && !isblank2(buf[i+1]))
			partial_tok = buf+i+1;
	}
	partial_tok_len = strnlen(partial_tok, RDLINE_BUF_SIZE);

	/* first call -> do a first pass */
	if (*state <= 0) {
		debug_printf("try complete <%s>\n", buf);
		debug_printf("there is %d complete tokens, <%s> is incomplete\n",
			     nb_token, partial_tok);

		nb_completable = 0;
		nb_non_completable = 0;

		inst = ctx[inst_num];
		while (inst) {
			/* parse the first tokens of the inst */
			if (nb_token &&
			    match_inst(inst, buf, nb_token, NULL, 0))
				goto next;

			debug_printf("instruction match\n");
			token_p = get_token(inst, nb_token);
			if (token_p)
				memcpy(&token_hdr, token_p, sizeof(token_hdr));

			/* non completable */
			if (!token_p ||
			    !token_hdr.ops->complete_get_nb ||
			    !token_hdr.ops->complete_get_elt ||
			    (n = token_hdr.ops->complete_get_nb(token_p)) == 0) {
				nb_non_completable++;
				goto next;
			}

			debug_printf("%d choices for this token\n", n);
			for (i=0 ; i<n ; i++) {
				if (token_hdr.ops->complete_get_elt(token_p, i,
								    tmpbuf,
								    sizeof(tmpbuf)) < 0)
					continue;

				/* we have at least room for one char */
				tmp_len = strnlen(tmpbuf, sizeof(tmpbuf));
				if (tmp_len < CMDLINE_BUFFER_SIZE - 1) {
					tmpbuf[tmp_len] = ' ';
					tmpbuf[tmp_len+1] = 0;
				}

				debug_printf("   choice <%s>\n", tmpbuf);

				/* does the completion match the
				 * beginning of the word ? */
				if (!strncmp(partial_tok, tmpbuf,
					     partial_tok_len)) {
					if (comp_len == -1) {
						snprintf(comp_buf, sizeof(comp_buf),
							 "%s", tmpbuf + partial_tok_len);
						comp_len =
							strnlen(tmpbuf + partial_tok_len,
									sizeof(tmpbuf) - partial_tok_len);

					}
					else {
						comp_len =
							nb_common_chars(comp_buf,
									tmpbuf+partial_tok_len);
						comp_buf[comp_len] = 0;
					}
					nb_completable++;
				}
			}
		next:
			debug_printf("next\n");
			inst_num ++;
			inst = ctx[inst_num];
		}

		debug_printf("total choices %d for this completion\n",
			     nb_completable);

		/* no possible completion */
		if (nb_completable == 0 && nb_non_completable == 0)
			return 0;

		/* if multichoice is not required */
		if (*state == 0 && partial_tok_len > 0) {
			/* one or several choices starting with the
			   same chars */
			if (comp_len > 0) {
				if ((unsigned)(comp_len + 1) > size)
					return 0;

				snprintf(dst, size, "%s", comp_buf);
				dst[comp_len] = 0;
				return 2;
			}
		}
	}

	/* init state correctly */
	if (*state == -1)
		*state = 0;

	debug_printf("Multiple choice STATE=%d\n", *state);

	inst_num = 0;
	inst = ctx[inst_num];
	while (inst) {
		/* we need to redo it */
		inst = ctx[inst_num];

		if (nb_token &&
		    match_inst(inst, buf, nb_token, NULL, 0))
			goto next2;

		token_p = get_token(inst, nb_token);
		if (token_p)
			memcpy(&token_hdr, token_p, sizeof(token_hdr));

		/* one choice for this token */
		if (!token_p ||
		    !token_hdr.ops->complete_get_nb ||
		    !token_hdr.ops->complete_get_elt ||
		    (n = token_hdr.ops->complete_get_nb(token_p)) == 0) {
			if (local_state < *state) {
				local_state++;
				goto next2;
			}
			(*state)++;
			if (token_p && token_hdr.ops->get_help) {
				token_hdr.ops->get_help(token_p, tmpbuf,
							sizeof(tmpbuf));
				help_str = inst->help_str;
				if (help_str)
					snprintf(dst, size, "[%s]: %s", tmpbuf,
						 help_str);
				else
					snprintf(dst, size, "[%s]: No help",
						 tmpbuf);
			}
			else {
				snprintf(dst, size, "[RETURN]");
			}
			return 1;
		}

		/* several choices */
		for (i=0 ; i<n ; i++) {
			if (token_hdr.ops->complete_get_elt(token_p, i, tmpbuf,
							    sizeof(tmpbuf)) < 0)
				continue;
			/* we have at least room for one char */
			tmp_len = strnlen(tmpbuf, sizeof(tmpbuf));
			if (tmp_len < CMDLINE_BUFFER_SIZE - 1) {
				tmpbuf[tmp_len] = ' ';
				tmpbuf[tmp_len + 1] = 0;
			}

			debug_printf("   choice <%s>\n", tmpbuf);

			/* does the completion match the beginning of
			 * the word ? */
			if (!strncmp(partial_tok, tmpbuf,
				     partial_tok_len)) {
				if (local_state < *state) {
					local_state++;
					continue;
				}
				(*state)++;
				l=snprintf(dst, size, "%s", tmpbuf);
				if (l>=0 && token_hdr.ops->get_help) {
					token_hdr.ops->get_help(token_p, tmpbuf,
								sizeof(tmpbuf));
					help_str = inst->help_str;
					if (help_str)
						snprintf(dst+l, size-l, "[%s]: %s",
							 tmpbuf, help_str);
					else
						snprintf(dst+l, size-l,
							 "[%s]: No help", tmpbuf);
				}

				return 1;
			}
		}
	next2:
		inst_num ++;
		inst = ctx[inst_num];
	}
	return 0;
}
示例#2
0
int
cmdline_parse(struct cmdline *cl, const char * buf)
{
	unsigned int inst_num=0;
	cmdline_parse_inst_t *inst;
	const char *curbuf;
	union {
		char buf[CMDLINE_PARSE_RESULT_BUFSIZE];
		long double align; /* strong alignment constraint for buf */
	} result, tmp_result;
	void (*f)(void *, struct cmdline *, void *) = NULL;
	void *data = NULL;
	int comment = 0;
	int linelen = 0;
	int parse_it = 0;
	int err = CMDLINE_PARSE_NOMATCH;
	int tok;
	cmdline_parse_ctx_t *ctx;
#ifdef RTE_LIBRTE_CMDLINE_DEBUG
	char debug_buf[BUFSIZ];
#endif

	if (!cl || !buf)
		return CMDLINE_PARSE_BAD_ARGS;

	ctx = cl->ctx;

	/*
	 * - look if the buffer contains at least one line
	 * - look if line contains only spaces or comments
	 * - count line length
	 */
	curbuf = buf;
	while (! isendofline(*curbuf)) {
		if ( *curbuf == '\0' ) {
			debug_printf("Incomplete buf (len=%d)\n", linelen);
			return 0;
		}
		if ( iscomment(*curbuf) ) {
			comment = 1;
		}
		if ( ! isblank2(*curbuf) && ! comment) {
			parse_it = 1;
		}
		curbuf++;
		linelen++;
	}

	/* skip all endofline chars */
	while (isendofline(buf[linelen])) {
		linelen++;
	}

	/* empty line */
	if ( parse_it == 0 ) {
		debug_printf("Empty line (len=%d)\n", linelen);
		return linelen;
	}

#ifdef RTE_LIBRTE_CMDLINE_DEBUG
	snprintf(debug_buf, (linelen>64 ? 64 : linelen), "%s", buf);
	debug_printf("Parse line : len=%d, <%s>\n", linelen, debug_buf);
#endif

	/* parse it !! */
	inst = ctx[inst_num];
	while (inst) {
		debug_printf("INST %d\n", inst_num);

		/* fully parsed */
		tok = match_inst(inst, buf, 0, tmp_result.buf,
				 sizeof(tmp_result.buf));

		if (tok > 0) /* we matched at least one token */
			err = CMDLINE_PARSE_BAD_ARGS;

		else if (!tok) {
			debug_printf("INST fully parsed\n");
			memcpy(&result, &tmp_result,
			       sizeof(result));
			/* skip spaces */
			while (isblank2(*curbuf)) {
				curbuf++;
			}

			/* if end of buf -> there is no garbage after inst */
			if (isendofline(*curbuf) || iscomment(*curbuf)) {
				if (!f) {
					memcpy(&f, &inst->f, sizeof(f));
					memcpy(&data, &inst->data, sizeof(data));
				}
				else {
					/* more than 1 inst matches */
					err = CMDLINE_PARSE_AMBIGUOUS;
					f=NULL;
					debug_printf("Ambiguous cmd\n");
					break;
				}
			}
		}

		inst_num ++;
		inst = ctx[inst_num];
	}

	/* call func */
	if (f) {
		f(result.buf, cl, data);
	}

	/* no match */
	else {
		debug_printf("No match err=%d\n", err);
		return err;
	}

	return linelen;
}
示例#3
0
static boolean
parse_instruction(
   struct translate_ctx *ctx,
   boolean has_label )
{
   uint i;
   uint saturate = 0;
   const struct tgsi_opcode_info *info;
   struct tgsi_full_instruction inst;
   const char *cur;
   uint advance;

   inst = tgsi_default_full_instruction();

   /* Parse predicate.
    */
   eat_opt_white( &ctx->cur );
   if (*ctx->cur == '(') {
      uint file;
      int index;
      uint swizzle[4];
      boolean parsed_swizzle;

      inst.Instruction.Predicate = 1;

      ctx->cur++;
      if (*ctx->cur == '!') {
         ctx->cur++;
         inst.Predicate.Negate = 1;
      }

      if (!parse_register_1d( ctx, &file, &index ))
         return FALSE;

      if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 4 )) {
         if (parsed_swizzle) {
            inst.Predicate.SwizzleX = swizzle[0];
            inst.Predicate.SwizzleY = swizzle[1];
            inst.Predicate.SwizzleZ = swizzle[2];
            inst.Predicate.SwizzleW = swizzle[3];
         }
      }

      if (*ctx->cur != ')') {
         report_error( ctx, "Expected `)'" );
         return FALSE;
      }

      ctx->cur++;
   }

   /* Parse instruction name.
    */
   eat_opt_white( &ctx->cur );
   for (i = 0; i < TGSI_OPCODE_LAST; i++) {
      cur = ctx->cur;

      info = tgsi_get_opcode_info( i );
      if (match_inst(&cur, &saturate, info)) {
         if (info->num_dst + info->num_src + info->is_tex == 0) {
            ctx->cur = cur;
            break;
         }
         else if (*cur == '\0' || eat_white( &cur )) {
            ctx->cur = cur;
            break;
         }
      }
   }
   if (i == TGSI_OPCODE_LAST) {
      if (has_label)
         report_error( ctx, "Unknown opcode" );
      else
         report_error( ctx, "Expected `DCL', `IMM' or a label" );
      return FALSE;
   }

   inst.Instruction.Opcode = i;
   inst.Instruction.Saturate = saturate;
   inst.Instruction.NumDstRegs = info->num_dst;
   inst.Instruction.NumSrcRegs = info->num_src;

   if (i >= TGSI_OPCODE_SAMPLE && i <= TGSI_OPCODE_GATHER4) {
      /*
       * These are not considered tex opcodes here (no additional
       * target argument) however we're required to set the Texture
       * bit so we can set the number of tex offsets.
       */
      inst.Instruction.Texture = 1;
      inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
   }

   if ((i >= TGSI_OPCODE_LOAD && i <= TGSI_OPCODE_ATOMIMAX) ||
       i == TGSI_OPCODE_RESQ) {
      inst.Instruction.Memory = 1;
      inst.Memory.Qualifier = 0;
   }

   /* Parse instruction operands.
    */
   for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
      if (i > 0) {
         eat_opt_white( &ctx->cur );
         if (*ctx->cur != ',') {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         ctx->cur++;
         eat_opt_white( &ctx->cur );
      }

      if (i < info->num_dst) {
         if (!parse_dst_operand( ctx, &inst.Dst[i] ))
            return FALSE;
      }
      else if (i < info->num_dst + info->num_src) {
         if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
            return FALSE;
      }
      else {
         uint j;

         for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
            if (str_match_nocase_whole( &ctx->cur, tgsi_texture_names[j] )) {
               inst.Instruction.Texture = 1;
               inst.Texture.Texture = j;
               break;
            }
         }
         if (j == TGSI_TEXTURE_COUNT) {
            report_error( ctx, "Expected texture target" );
            return FALSE;
         }
      }
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   for (i = 0; inst.Instruction.Texture && *cur == ','; i++) {
         cur++;
         eat_opt_white( &cur );
         ctx->cur = cur;
         if (!parse_texoffset_operand( ctx, &inst.TexOffsets[i] ))
            return FALSE;
         cur = ctx->cur;
         eat_opt_white( &cur );
   }
   inst.Texture.NumOffsets = i;

   cur = ctx->cur;
   eat_opt_white(&cur);
   for (i = 0; inst.Instruction.Memory && *cur == ','; i++) {
      uint j;
      cur++;
      eat_opt_white(&cur);
      ctx->cur = cur;
      for (j = 0; j < 3; j++) {
         if (str_match_nocase_whole(&ctx->cur, tgsi_memory_names[j])) {
            inst.Memory.Qualifier |= 1U << j;
            break;
         }
      }
      if (j == 3) {
         report_error(ctx, "Expected memory qualifier");
         return FALSE;
      }
      cur = ctx->cur;
      eat_opt_white(&cur);
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (info->is_branch && *cur == ':') {
      uint target;

      cur++;
      eat_opt_white( &cur );
      if (!parse_uint( &cur, &target )) {
         report_error( ctx, "Expected a label" );
         return FALSE;
      }
      inst.Instruction.Label = 1;
      inst.Label.Label = target;
      ctx->cur = cur;
   }

   advance = tgsi_build_full_instruction(
      &inst,
      ctx->tokens_cur,
      ctx->header,
      (uint) (ctx->tokens_end - ctx->tokens_cur) );
   if (advance == 0)
      return FALSE;
   ctx->tokens_cur += advance;

   return TRUE;
}
示例#4
0
int8_t 
complete(parse_pgm_ctx_t ctx[], const char *buf, int16_t *state, 
	 char *dst, uint8_t size)
{
	const char * incomplete_token = buf;
	uint8_t inst_num = 0;
	parse_pgm_inst_t *inst;
	parse_pgm_token_hdr_t *token_p;
	struct token_hdr token_hdr;
	char tmpbuf[64], completion_buf[64];
	uint8_t incomplete_token_len;
	int8_t completion_len = -1;
	int8_t nb_token = 0;
	uint8_t i, n;
	int8_t l;
	uint8_t nb_completable;
	uint8_t nb_non_completable;
	uint16_t local_state=0;
	prog_char *help_str;

	debug_printf("%s called\n", __FUNCTION__);
	/* count the number of complete token to parse */
	for (i=0 ; buf[i] ; i++) {
		if (!isblank(buf[i]) && isblank(buf[i+1]))
			nb_token++;
		if (isblank(buf[i]) && !isblank(buf[i+1]))
			incomplete_token = buf+i+1;
	}
	incomplete_token_len = strlen(incomplete_token);

	/* first call -> do a first pass */
	if (*state <= 0) {
		debug_printf("try complete <%s>\n", buf);
		debug_printf("there is %d complete tokens, <%s> is incomplete\n", nb_token, incomplete_token);

		nb_completable = 0;
		nb_non_completable = 0;
		
		inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num);
		while (inst) {
			/* parse the first tokens of the inst */
			if (nb_token && match_inst(inst, buf, nb_token, NULL))
				goto next;
			
			debug_printf("instruction match \n");
			token_p = (parse_pgm_token_hdr_t *) pgm_read_word(&inst->tokens[nb_token]);
			if (token_p)
				memcpy_P(&token_hdr, token_p, sizeof(token_hdr));

			/* non completable */
			if (!token_p || 
			    !token_hdr.ops->complete_get_nb || 
			    !token_hdr.ops->complete_get_elt || 
			    (n = token_hdr.ops->complete_get_nb(token_p)) == 0) {
				nb_non_completable++;
				goto next;
			}

			debug_printf("%d choices for this token\n", n);
			for (i=0 ; i<n ; i++) {
				if (token_hdr.ops->complete_get_elt(token_p, i, tmpbuf, sizeof(tmpbuf)) < 0)
					continue;
				strcat_P(tmpbuf, PSTR(" ")); /* we have at least room for one char */
				debug_printf("   choice <%s>\n", tmpbuf);
				/* does the completion match the beginning of the word ? */
				if (!strncmp(incomplete_token, tmpbuf, incomplete_token_len)) {
					if (completion_len == -1) {
						strcpy(completion_buf, tmpbuf+incomplete_token_len);
						completion_len = strlen(tmpbuf+incomplete_token_len);
						
					}
					else {
						completion_len = nb_common_chars(completion_buf, 
										 tmpbuf+incomplete_token_len);
						completion_buf[completion_len] = 0;
					}
					nb_completable++;
				}
			}		
		next:
			inst_num ++;
			inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num);
		}

		debug_printf("total choices %d for this completion\n", nb_completable);

		/* no possible completion */
		if (nb_completable == 0 && nb_non_completable == 0)
			return 0;
		
		/* if multichoice is not required */
		if (*state == 0 && incomplete_token_len > 0) {
			/* one or several choices starting with the
			   same chars */
			if (completion_len > 0) { 
				if (completion_len + 1 > size)
					return 0;
				
				strcpy(dst, completion_buf);
				return 2;
			}
		}
	}

	/* init state correctly */
	if (*state == -1)
		*state = 0;

	debug_printf("Multiple choice STATE=%d\n", *state);

	inst_num = 0;
	inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num);
	while (inst) {
		/* we need to redo it */
		inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num);
		
		if (nb_token && match_inst(inst, buf, nb_token, NULL))
			goto next2;
		
		token_p = (parse_pgm_token_hdr_t *)pgm_read_word(&inst->tokens[nb_token]);
		if (token_p)
			memcpy_P(&token_hdr, token_p, sizeof(token_hdr));

		/* one choice for this token */
		if (!token_p || 
		    !token_hdr.ops->complete_get_nb || 
		    !token_hdr.ops->complete_get_elt || 
		    (n = token_hdr.ops->complete_get_nb(token_p)) == 0) {
			if (local_state < *state) {
				local_state++;
				goto next2;
			}
			(*state)++;
			if (token_p && token_hdr.ops->get_help) {
				token_hdr.ops->get_help(token_p, tmpbuf, sizeof(tmpbuf));
				help_str = (prog_char *) pgm_read_word(&inst->help_str);
				if (help_str)
					snprintf_P(dst, size, PSTR("[%s]: %S"), tmpbuf, help_str);
				else
					snprintf_P(dst, size, PSTR("[%s]: No help"), tmpbuf);
			}
			else {
				snprintf_P(dst, size, PSTR("[RETURN]"));
			}
			return 1;
		}

		/* several choices */
		for (i=0 ; i<n ; i++) {
			if (token_hdr.ops->complete_get_elt(token_p, i, tmpbuf, sizeof(tmpbuf)) < 0)
				continue;
			strcat_P(tmpbuf, PSTR(" ")); /* we have at least room for one char */
			debug_printf("   choice <%s>\n", tmpbuf);
			/* does the completion match the beginning of the word ? */
			if (!strncmp(incomplete_token, tmpbuf, incomplete_token_len)) {
				if (local_state < *state) {
					local_state++;
					continue;
				}
				(*state)++;
				l=snprintf(dst, size, "%s", tmpbuf);
				if (l>=0 && token_hdr.ops->get_help) {
					token_hdr.ops->get_help(token_p, tmpbuf, sizeof(tmpbuf));
					help_str = (prog_char *) pgm_read_word(&inst->help_str);
					if (help_str)
						snprintf_P(dst+l, size-l, PSTR("[%s]: %S"), tmpbuf, help_str);
					else
						snprintf_P(dst+l, size-l, PSTR("[%s]: No help"), tmpbuf);
				}
							      
				return 1;
			}
		}
	next2:
		inst_num ++;
		inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num);
	}
	return 0;
}
示例#5
0
int8_t
parse(parse_pgm_ctx_t ctx[], const char * buf)
{
	uint8_t inst_num=0;
	parse_pgm_inst_t * inst;
	const char * curbuf;
	char result_buf[256]; /* XXX align, size zé in broblém */
	void (*f)(void *, void *) = NULL;
	void * data = NULL;
	int comment = 0;
	int linelen = 0;
	int parse_it = 0;
	int8_t err = PARSE_NOMATCH;
	int8_t tok;
#ifdef CMDLINE_DEBUG
	char debug_buf[64];
#endif

	/* 
	 * - look if the buffer contains at least one line
	 * - look if line contains only spaces or comments 
	 * - count line length
	 */
	curbuf = buf;
	while (! isendofline(*curbuf)) {
		if ( *curbuf == '\0' ) {
			debug_printf("Incomplete buf (len=%d)\n", linelen);
			return 0;
		}
		if ( iscomment(*curbuf) ) {
			comment = 1;
		}
		if ( ! isblank(*curbuf) && ! comment) {
			parse_it = 1;
		}
		curbuf++;
		linelen++;
	}

	/* skip all endofline chars */
	while (isendofline(buf[linelen])) {
		linelen++;
	}

	/* empty line */
	if ( parse_it == 0 ) {
		debug_printf("Empty line (len=%d)\n", linelen);
		return linelen;
	}

#ifdef CMDLINE_DEBUG
	snprintf(debug_buf, (linelen>64 ? 64 : linelen), "%s", buf);
	debug_printf("Parse line : len=%d, <%s>\n", linelen, debug_buf);
#endif

	/* parse it !! */
	inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num);
	while (inst) {
		debug_printf("INST\n");

		/* fully parsed */
		tok = match_inst(inst, buf, 0, result_buf);

		if (tok > 0) /* we matched at least one token */
			err = PARSE_BAD_ARGS;

		else if (!tok) {
			debug_printf("INST fully parsed\n");
			/* skip spaces */
			while (isblank(*curbuf)) {
				curbuf++;
			}
			
			/* if end of buf -> there is no garbage after inst */
			if (isendofline(*curbuf) || iscomment(*curbuf)) {
				if (!f) {
					memcpy_P(&f, &inst->f, sizeof(f));
					memcpy_P(&data, &inst->data, sizeof(data));
				}
				else {
					/* more than 1 inst matches */
					err = PARSE_AMBIGUOUS;
					f=NULL;
					debug_printf("Ambiguous cmd\n");
					break;
				}
			}
		}
			
		inst_num ++;
		inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num);
	}
	
	/* call func */
	if (f) {
		f(result_buf, data);
	}

	/* no match */
	else {
		debug_printf("No match err=%d\n", err);
		return err;
	}
	
	return linelen;
}
示例#6
0
文件: tgsi_text.c 项目: chemecse/mesa
static boolean
parse_instruction(
   struct translate_ctx *ctx,
   boolean has_label )
{
   uint i;
   uint saturate = 0;
   uint precise = 0;
   const struct tgsi_opcode_info *info;
   struct tgsi_full_instruction inst;
   const char *cur;
   uint advance;

   inst = tgsi_default_full_instruction();

   /* Parse instruction name.
    */
   eat_opt_white( &ctx->cur );
   for (i = 0; i < TGSI_OPCODE_LAST; i++) {
      cur = ctx->cur;

      info = tgsi_get_opcode_info( i );
      if (match_inst(&cur, &saturate, &precise, info)) {
         if (info->num_dst + info->num_src + info->is_tex == 0) {
            ctx->cur = cur;
            break;
         }
         else if (*cur == '\0' || eat_white( &cur )) {
            ctx->cur = cur;
            break;
         }
      }
   }
   if (i == TGSI_OPCODE_LAST) {
      if (has_label)
         report_error( ctx, "Unknown opcode" );
      else
         report_error( ctx, "Expected `DCL', `IMM' or a label" );
      return FALSE;
   }

   inst.Instruction.Opcode = i;
   inst.Instruction.Saturate = saturate;
   inst.Instruction.Precise = precise;
   inst.Instruction.NumDstRegs = info->num_dst;
   inst.Instruction.NumSrcRegs = info->num_src;

   if (i >= TGSI_OPCODE_SAMPLE && i <= TGSI_OPCODE_GATHER4) {
      /*
       * These are not considered tex opcodes here (no additional
       * target argument) however we're required to set the Texture
       * bit so we can set the number of tex offsets.
       */
      inst.Instruction.Texture = 1;
      inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
   }

   if ((i >= TGSI_OPCODE_LOAD && i <= TGSI_OPCODE_ATOMIMAX) ||
       i == TGSI_OPCODE_RESQ) {
      inst.Instruction.Memory = 1;
      inst.Memory.Qualifier = 0;
   }

   assume(info->num_dst <= TGSI_FULL_MAX_DST_REGISTERS);
   assume(info->num_src <= TGSI_FULL_MAX_SRC_REGISTERS);

   /* Parse instruction operands.
    */
   for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
      if (i > 0) {
         eat_opt_white( &ctx->cur );
         if (*ctx->cur != ',') {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         ctx->cur++;
         eat_opt_white( &ctx->cur );
      }

      if (i < info->num_dst) {
         if (!parse_dst_operand( ctx, &inst.Dst[i] ))
            return FALSE;
      }
      else if (i < info->num_dst + info->num_src) {
         if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
            return FALSE;
      }
      else {
         uint j;

         for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
            if (str_match_nocase_whole( &ctx->cur, tgsi_texture_names[j] )) {
               inst.Instruction.Texture = 1;
               inst.Texture.Texture = j;
               break;
            }
         }
         if (j == TGSI_TEXTURE_COUNT) {
            report_error( ctx, "Expected texture target" );
            return FALSE;
         }
      }
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   for (i = 0; inst.Instruction.Texture && *cur == ',' && i < TGSI_FULL_MAX_TEX_OFFSETS; i++) {
         cur++;
         eat_opt_white( &cur );
         ctx->cur = cur;
         if (!parse_texoffset_operand( ctx, &inst.TexOffsets[i] ))
            return FALSE;
         cur = ctx->cur;
         eat_opt_white( &cur );
   }
   inst.Texture.NumOffsets = i;

   cur = ctx->cur;
   eat_opt_white(&cur);

   for (; inst.Instruction.Memory && *cur == ',';
        ctx->cur = cur, eat_opt_white(&cur)) {
      int j;

      cur++;
      eat_opt_white(&cur);

      j = str_match_name_from_array(&cur, tgsi_memory_names,
                                    ARRAY_SIZE(tgsi_memory_names));
      if (j >= 0) {
         inst.Memory.Qualifier |= 1U << j;
         continue;
      }

      j = str_match_name_from_array(&cur, tgsi_texture_names,
                                    ARRAY_SIZE(tgsi_texture_names));
      if (j >= 0) {
         inst.Memory.Texture = j;
         continue;
      }

      j = str_match_format(&cur);
      if (j >= 0) {
         inst.Memory.Format = j;
         continue;
      }

      ctx->cur = cur;
      report_error(ctx, "Expected memory qualifier, texture target, or format\n");
      return FALSE;
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (info->is_branch && *cur == ':') {
      uint target;

      cur++;
      eat_opt_white( &cur );
      if (!parse_uint( &cur, &target )) {
         report_error( ctx, "Expected a label" );
         return FALSE;
      }
      inst.Instruction.Label = 1;
      inst.Label.Label = target;
      ctx->cur = cur;
   }

   advance = tgsi_build_full_instruction(
      &inst,
      ctx->tokens_cur,
      ctx->header,
      (uint) (ctx->tokens_end - ctx->tokens_cur) );
   if (advance == 0)
      return FALSE;
   ctx->tokens_cur += advance;

   return TRUE;
}