예제 #1
0
파일: x-ycp.c 프로젝트: Distrotech/gettext
/* Extract messages until the next balanced closing parenthesis.
   Extracted messages are added to MLP.
   Return true upon eof, false upon closing parenthesis.  */
static bool
extract_parenthesized (message_list_ty *mlp,
                       flag_context_ty outer_context,
                       flag_context_list_iterator_ty context_iter,
                       bool in_i18n)
{
  int state; /* 1 or 2 inside _( ... ), otherwise 0 */
  int plural_state = 0; /* defined only when in states 1 and 2 */
  message_ty *plural_mp = NULL; /* defined only when in states 1 and 2 */
  /* Context iterator that will be used if the next token is a '('.  */
  flag_context_list_iterator_ty next_context_iter =
    passthrough_context_list_iterator;
  /* Current context.  */
  flag_context_ty inner_context =
    inherited_context (outer_context,
                       flag_context_list_iterator_advance (&context_iter));

  /* Start state is 0 or 1.  */
  state = (in_i18n ? 1 : 0);

  for (;;)
    {
      token_ty token;

      if (in_i18n)
        phase8_get (&token);
      else
        phase5_get (&token);

      switch (token.type)
        {
        case token_type_i18n:
          if (extract_parenthesized (mlp, inner_context, next_context_iter,
                                     true))
            return true;
          next_context_iter = null_context_list_iterator;
          state = 0;
          continue;

        case token_type_string_literal:
          if (state == 1)
            {
              lex_pos_ty pos;
              pos.file_name = logical_file_name;
              pos.line_number = token.line_number;

              if (plural_state == 0)
                {
                  /* Seen an msgid.  */
                  plural_mp = remember_a_message (mlp, NULL, token.string,
                                                  inner_context, &pos,
                                                  NULL, token.comment);
                  plural_state = 1;
                  state = 2;
                }
              else
                {
                  /* Seen an msgid_plural.  */
                  if (plural_mp != NULL)
                    remember_a_message_plural (plural_mp, token.string,
                                               inner_context, &pos,
                                               token.comment);
                  state = 0;
                }
              drop_reference (token.comment);
            }
          else
            {
              free_token (&token);
              state = 0;
            }
          next_context_iter = null_context_list_iterator;
          continue;

        case token_type_symbol:
          next_context_iter =
            flag_context_list_iterator (
              flag_context_list_table_lookup (
                flag_context_list_table,
                token.string, strlen (token.string)));
          free_token (&token);
          state = 0;
          continue;

        case token_type_lparen:
          if (extract_parenthesized (mlp, inner_context, next_context_iter,
                                     false))
            return true;
          next_context_iter = null_context_list_iterator;
          state = 0;
          continue;

        case token_type_rparen:
          return false;

        case token_type_comma:
          if (state == 2)
            state = 1;
          else
            state = 0;
          inner_context =
            inherited_context (outer_context,
                               flag_context_list_iterator_advance (
                                 &context_iter));
          next_context_iter = passthrough_context_list_iterator;
          continue;

        case token_type_other:
          next_context_iter = null_context_list_iterator;
          state = 0;
          continue;

        case token_type_eof:
          return true;

        default:
          abort ();
        }
    }
}
예제 #2
0
void
extract_smalltalk (FILE *f,
		   const char *real_filename, const char *logical_filename,
		   flag_context_list_table_ty *flag_table,
		   msgdomain_list_ty *mdlp)
{
  message_list_ty *mlp = mdlp->item[0]->messages;

  fp = f;
  real_file_name = real_filename;
  logical_file_name = xstrdup (logical_filename);
  line_number = 1;

  last_comment_line = -1;
  last_non_comment_line = -1;

  /* Eat tokens until eof is seen.  */
  {
    /* 0 when no "NLS" has been seen.
       1 after "NLS".
       2 after "NLS ?".
       3 after "NLS at:".
       4 after "NLS at: <string>".
       5 after "NLS at: <string> plural:".  */
    int state;
    /* Remember the message containing the msgid, for msgid_plural.
       Non-NULL in states 4, 5.  */
    message_ty *plural_mp = NULL;

    /* Start state is 0.  */
    state = 0;

    for (;;)
      {
	token_ty token;

	x_smalltalk_lex (&token);

	switch (token.type)
	  {
	  case token_type_symbol:
	    state = (strcmp (token.string, "NLS") == 0 ? 1 :
		     strcmp (token.string, "?") == 0 && state == 1 ? 2 :
		     strcmp (token.string, "at:") == 0 && state == 1 ? 3 :
		     strcmp (token.string, "plural:") == 0 && state == 4 ? 5 :
		     0);
	    free (token.string);
	    break;

	  case token_type_string_literal:
	    if (state == 2)
	      {
		lex_pos_ty pos;
		pos.file_name = logical_file_name;
		pos.line_number = token.line_number;
		remember_a_message (mlp, NULL, token.string, null_context,
				    &pos, savable_comment);
		state = 0;
		break;
	      }
	    if (state == 3)
	      {
		lex_pos_ty pos;
		pos.file_name = logical_file_name;
		pos.line_number = token.line_number;
		plural_mp = remember_a_message (mlp, NULL, token.string,
						null_context, &pos,
						savable_comment);
		state = 4;
		break;
	      }
	    if (state == 5)
	      {
		lex_pos_ty pos;
		pos.file_name = logical_file_name;
		pos.line_number = token.line_number;
		remember_a_message_plural (plural_mp, token.string,
					   null_context, &pos,
					   savable_comment);
		state = 0;
		break;
	      }
	    state = 0;
	    free (token.string);
	    break;

	  case token_type_uniq:
	  case token_type_other:
	    state = 0;
	    break;

	  case token_type_eof:
	    break;

	  default:
	    abort ();
	  }

	if (token.type == token_type_eof)
	  break;
      }
  }

  /* Close scanner.  */
  fp = NULL;
  real_file_name = NULL;
  logical_file_name = NULL;
  line_number = 0;
}