示例#1
0
wxString pgsRecord::value() const
{
	wxString data;
	pgsVarMap vars;

	// Go through each line and enclose it into braces
	for (USHORT i = 0; i < count_lines(); i++)
	{
		data += wxT("(");

		// Go through each column and separate them with commas
		for (USHORT j = 0; j < count_columns(); j++)
		{
			wxString elm(m_record[i][j]->eval(vars)->value());
			if (!m_record[i][j]->is_number())
			{
				elm.Replace(wxT("\\"), wxT("\\\\"));
				elm.Replace(wxT("\""), wxT("\\\""));
				elm = wxT("\"") + elm + wxT("\"");
			}
			data += elm + (j != count_columns() - 1 ? wxT(",") : wxT(""));
		}

		data += (i == count_lines() - 1) ? wxT(")") : wxT(")\n");
	}

	// Return the string representation of the record
	return data;
}
示例#2
0
USHORT pgsRecord::get_column(wxString name) const
{
	name = name.Strip(wxString::both).Lower();
	if (name.IsEmpty())
	{
		return count_columns();
	}
	for (USHORT i = 0; i < count_columns(); i++)
	{
		if (m_columns[i] == name)
			return i;
	}
	return count_columns();
}
示例#3
0
bool pgsRecord::newline()
{
	// Insert a line
	m_record.Add(pgsVectorRecordLine());
	// Initialize each column of the line with an empty string
	for (USHORT i = 0; i < count_columns(); i++)
	{
		m_record.Last().Add(pnew pgsString(wxT("")));
	}
	return true;
}
示例#4
0
pgsOperand pgsRecord::get(const USHORT &line,
                          const USHORT &column) const
{
	if (line < count_lines() && column < count_columns())
	{
		return m_record[line][column];
	}
	else
	{
		return pnew pgsString(wxT(""));
	}
}
示例#5
0
pgsOperand pgsRecord::pgs_not() const
{
	if (pgs_is_true())
	{
		// A record with no line is false
		return pnew pgsRecord(count_columns());
	}
	else
	{
		// A record with at least one line is true
		pgsRecord *copy = pnew pgsRecord(*this);
		copy->newline();
		return copy; // Insert one line and return the record
	}
}
示例#6
0
pgsOperand pgsRecord::get_line(const USHORT &line) const
{
	if (line < count_lines())
	{
		pgsRecord *rec = pnew pgsRecord(count_columns());
		rec->m_columns = this->m_columns;
		rec->newline();
		rec->m_record[0] = this->m_record[line];
		return rec;
	}
	else
	{
		return pnew pgsRecord(0);
	}
}
示例#7
0
bool pgsRecord::insert(const USHORT &line, const USHORT &column,
                       pgsOperand value)
{
	// Add lines to match the line number provided
	for (USHORT i = count_lines(); i <= line; i++)
	{
		newline();
	}

	// Cannot insert if column is invalid
	if (column >= count_columns())
	{
		return false;
	}
	// Insert the value at line.column
	else
	{
		m_record[line][column] = value;
		return true;
	}
}
示例#8
0
bool pgsRecord::set_column_name(const USHORT &column, wxString name)
{
	// Column number must be valid
	if (column >= count_columns())
	{
		return false;
	}

	// Column name must not exist
	// Column name must not be empty
	name = name.Strip(wxString::both).Lower();
	if (m_columns.Index(name) != wxNOT_FOUND || name.IsEmpty())
	{
		return false;
	}

	// Set the column name
	m_columns[column] = name;

	return true;
}
示例#9
0
int
main(int argc, char **argv)
{
    struct name_table_entry *name_table = typeCalloc(struct
						     name_table_entry, CAPTABSIZE);
    HashValue *hash_table = typeCalloc(HashValue, HASHTABSIZE);
    const char *root_name = "";
    int column = 0;
    int bigstring = 0;
    int n;
    char buffer[BUFSIZ];

    static const char *typenames[] =
    {"BOOLEAN", "NUMBER", "STRING"};

    short BoolCount = 0;
    short NumCount = 0;
    short StrCount = 0;

    /* The first argument is the column-number (starting with 0).
     * The second is the root name of the tables to generate.
     */
    if (argc <= 3
	|| (column = atoi(argv[1])) <= 0
	|| (column >= MAX_COLUMNS)
	|| *(root_name = argv[2]) == 0
	|| (bigstring = atoi(argv[3])) < 0
	|| name_table == 0
	|| hash_table == 0) {
	fprintf(stderr, "usage: make_hash column root_name bigstring\n");
	exit(EXIT_FAILURE);
    }

    /*
     * Read the table into our arrays.
     */
    for (n = 0; (n < CAPTABSIZE) && fgets(buffer, BUFSIZ, stdin);) {
	char **list, *nlp = strchr(buffer, '\n');
	if (nlp)
	    *nlp = '\0';
	list = parse_columns(buffer);
	if (list == 0)		/* blank or comment */
	    continue;
	if (column > count_columns(list)) {
	    fprintf(stderr, "expected %d columns, have %d:\n%s\n",
		    column,
		    count_columns(list),
		    buffer);
	    exit(EXIT_FAILURE);
	}
	name_table[n].nte_link = -1;	/* end-of-hash */
	name_table[n].nte_name = strmalloc(list[column]);
	if (!strcmp(list[2], "bool")) {
	    name_table[n].nte_type = BOOLEAN;
	    name_table[n].nte_index = BoolCount++;
	} else if (!strcmp(list[2], "num")) {
	    name_table[n].nte_type = NUMBER;
	    name_table[n].nte_index = NumCount++;
	} else if (!strcmp(list[2], "str")) {
	    name_table[n].nte_type = STRING;
	    name_table[n].nte_index = StrCount++;
	} else {
	    fprintf(stderr, "Unknown type: %s\n", list[2]);
	    exit(EXIT_FAILURE);
	}
	n++;
    }
    _nc_make_hash_table(name_table, hash_table);

    /*
     * Write the compiled tables to standard output
     */
    if (bigstring) {
	int len = 0;
	int nxt;

	printf("static const char %s_names_text[] = \\\n", root_name);
	for (n = 0; n < CAPTABSIZE; n++) {
	    nxt = (int) strlen(name_table[n].nte_name) + 5;
	    if (nxt + len > 72) {
		printf("\\\n");
		len = 0;
	    }
	    printf("\"%s\\0\" ", name_table[n].nte_name);
	    len += nxt;
	}
	printf(";\n\n");

	len = 0;
	printf("static name_table_data const %s_names_data[] =\n",
	       root_name);
	printf("{\n");
	for (n = 0; n < CAPTABSIZE; n++) {
	    printf("\t{ %15d,\t%10s,\t%3d, %3d }%c\n",
		   len,
		   typenames[name_table[n].nte_type],
		   name_table[n].nte_index,
		   name_table[n].nte_link,
		   n < CAPTABSIZE - 1 ? ',' : ' ');
	    len += (int) strlen(name_table[n].nte_name) + 1;
	}
	printf("};\n\n");
	printf("static struct name_table_entry *_nc_%s_table = 0;\n\n", root_name);
    } else {

	printf("static struct name_table_entry const _nc_%s_table[] =\n",
	       root_name);
	printf("{\n");
	for (n = 0; n < CAPTABSIZE; n++) {
	    _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) "\"%s\"",
			name_table[n].nte_name);
	    printf("\t{ %15s,\t%10s,\t%3d, %3d }%c\n",
		   buffer,
		   typenames[name_table[n].nte_type],
		   name_table[n].nte_index,
		   name_table[n].nte_link,
		   n < CAPTABSIZE - 1 ? ',' : ' ');
	}
	printf("};\n\n");
    }

    printf("static const HashValue _nc_%s_hash_table[%d] =\n",
	   root_name,
	   HASHTABSIZE + 1);
    printf("{\n");
    for (n = 0; n < HASHTABSIZE; n++) {
	printf("\t%3d,\n", hash_table[n]);
    }
    printf("\t0\t/* base-of-table */\n");
    printf("};\n\n");

    printf("#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n",
	   BoolCount, NumCount, StrCount);
    printf("#error\t--> term.h and comp_captab.c disagree about the <--\n");
    printf("#error\t--> numbers of booleans, numbers and/or strings <--\n");
    printf("#endif\n\n");

    free(hash_table);
    return EXIT_SUCCESS;
}
示例#10
0
void
print_comment ()
{
  register int column, format;
  enum codes comment_type;

  int start_column, found_column;
  int first_comment_line, right_margin;
  int boxed_comment, stars, blankline_delims, paragraph_break, merge_blank_comment_lines;

  int two_contiguous_comments = 0;
  int save_length = 0;
  char *save_ptr = 0;
  char *text_on_line = 0;
  char *line_break_ptr = 0;
  char *start_delim;

  char *line_preamble;
  int line_preamble_length, visible_preamble;
  int suppress_cdb = 0;

  /* GDB_HOOK_print_comment() */

  /* Increment the parser stack, as we will store some things
     there for dump_line to use. */
  inc_pstack ();

  /* Have to do it this way because this piece of shit program doesn't
     always place the last token code on the stack. */
  if (*(token + 1) == '/')
    comment_type = cplus_comment;
  else
    comment_type = comment;

  /* First, decide what kind of comment this is: C++, C, or boxed C.
     Even if this appears to be a normal C comment, we may change our
     minds if we find a star in the right column of the second line,
     in which case that's a boxed comment too. */
  if (comment_type == cplus_comment)
    {
      start_delim = "//";
      line_preamble = "// ";
      line_preamble_length = 3;
      visible_preamble = 1;
      boxed_comment = 0;
      stars = 0;
      blankline_delims = 0;
    }
  else if (*buf_ptr == '*' || *buf_ptr == '-' || *buf_ptr == '=' || *buf_ptr == '_'
	   || (parser_state_tos->col_1 && !format_col1_comments))
    /* Boxed comment.  This block of code will return. */
    {
      int comment_lines_count = 1;

      found_column = start_column = current_column () - 2;
      parser_state_tos->box_com = 1;
      parser_state_tos->com_col = found_column;

      if (blanklines_before_blockcomments)
	prefix_blankline_requested = 1;

      *e_com++ = '/';
      *e_com++ = '*';
      while (1)
	{
	  do
	    {
	      if (*buf_ptr == EOL)	/* Count line numbers within comment blocks */
		++line_no;
	      *e_com++ = *buf_ptr++;
	      CHECK_COM_SIZE;
	    }
	  while (*buf_ptr != '*' && buf_ptr < buf_end);

	  /* We have reached the end of the comment, and it's all on
	     this line. */
	  if (*buf_ptr == '*' && *(buf_ptr + 1) == '/')
	    {
	      if (buf_ptr == buf_end)
		fill_buffer ();

	      buf_ptr += 2;
	      if (buf_ptr == buf_end)
		fill_buffer ();

	      *e_com++ = '*';
	      *e_com++ = '/';
	      *e_com = '\0';
	      parser_state_tos->tos--;

	      /* If this is the only line of a boxed comment, it may
	         be after some other text (e.g., #if foo <comment>),
	         in which case we want to specify the correct column.
	         In the other cases, the leading spaces account for
	         the columns and we start it in column 1. */

	      if (comment_lines_count > 1)
		parser_state_tos->com_col = 1;
	      else
		parser_state_tos->com_col = found_column;
	      return;
	    }

	  /* End of the line, or end of file. */
	  if (buf_ptr == buf_end)
	    {
	      if (*(buf_ptr - 1) == EOL)
		{
		  *(--e_com) = '\0';
		  dump_line (true);
		  comment_lines_count++;
		  parser_state_tos->com_col = 1;
		}

	      fill_buffer ();
	      if (had_eof)
		{
		  *e_com++ = '\0';
		  parser_state_tos->tos--;
		  parser_state_tos->com_col = start_column;
		  return;
		}
	    }
	}
    }
  else
    {
      start_delim = "/*";
      line_preamble = 0;
      line_preamble_length = 0;
      visible_preamble = 0;
      boxed_comment = 0;
      stars = star_comment_cont;
      blankline_delims = comment_delimiter_on_blankline;
    }

  paragraph_break = 0;
  merge_blank_comment_lines = 0;
  first_comment_line = com_lines;
  right_margin = comment_max_col;

  /* Now, compute the correct indentation for this comment
     and whether or not it should be formatted. */
  found_column = current_column () - 2;

  if ((s_lab == e_lab) && (s_code == e_code))
    /* First handle comments which begin the line. */
    {
      if (parser_state_tos->col_1 && !format_col1_comments)
	{
	  format = format_col1_comments;
	  start_column = 1;
	}
      else if (s_com != e_com)
	/* The fool has a line consisting of two contiguous comments.
	   In this case, we don't try too hard, 'cause nothing will
	   look good. */
	{
	  format = 0;
	  start_column = found_column;
	  two_contiguous_comments = 1;
	}
      else
	{
	  format = format_comments;

	  if (parser_state_tos->ind_level <= 0
	      && (!parser_state_tos->in_stmt || (parser_state_tos->in_decl && parser_state_tos->paren_level == 0)))
	    start_column = found_column;
	  else
	    /* This comment is within a procedure or other code. */
	    {
	      start_column = compute_code_target () - unindent_displace;
	      if (start_column < 0)
		start_column = 1;
	    }
	}
    }
  else
    /* This comment follows code of some sort. */
    {
      int target;

      suppress_cdb = 1;

      /* First, compute where the comment SHOULD go. */
      if (parser_state_tos->decl_on_line)
	target = decl_com_ind;
      else if (else_or_endif)
	target = else_endif_col;
      else
	target = com_ind;

      /* Now determine if the code on the line is short enough
         to allow the comment to begin where it should. */
      if (s_code != e_code)
	start_column = count_columns (compute_code_target (), s_code, NULL_CHAR);
      else
	/* s_lab != e_lab : there is a label here. */
	start_column = count_columns (compute_label_target (), s_lab, NULL_CHAR);

      if (start_column < target)
	start_column = target;
      else
	{
	  /* If the too-long code is a pre-processor command,
	     start the comment 1 space afterwards, otherwise
	     start at the next tab mark. */
	  if (else_or_endif)
	    {
	      start_column++;
	      else_or_endif = false;
	    }
	  else
	    start_column += tabsize - ((start_column - 1) % tabsize);
	}

      format = format_comments;
    }

  if (!line_preamble)
    {
      line_preamble_length = 3;
      if (stars)
	{
	  line_preamble = " * ";
	  visible_preamble = 1;
	}
      else
	{
	  line_preamble = "   ";
	  visible_preamble = 0;
	}
    }

  /* These are the parser stack variables used to communicate
     formatting information to dump_line (). */
  parser_state_tos->com_col = (two_contiguous_comments ? 1 : start_column);
  parser_state_tos->box_com = boxed_comment;

  /* Output the beginning comment delimiter.  They are both two
     characters long. */
  *e_com++ = *start_delim;
  *e_com++ = *(start_delim + 1);
  column = start_column + 2;

  /* If the user specified -cdb, put the delimiter on one line. */
  if (blankline_delims && !suppress_cdb)
    {
      char *p = buf_ptr;

      *e_com = '\0';
      dump_line (true);

      /* Check if the delimiter was already on a line by itself,
         and skip whitespace if formating. */
      while (*p == ' ' || *p == TAB)
	p++;
      if (*p == EOL)
	buf_ptr = p + 1;
      else if (format)
	buf_ptr = p;
      if (buf_ptr >= buf_end)
	fill_buffer ();

      column = start_column;
      goto begin_line;
    }
  else if (format)
    {
      *e_com++ = ' ';
      column = start_column + 3;
      while (*buf_ptr == ' ' || *buf_ptr == TAB)
	if (++buf_ptr >= buf_end)
	  fill_buffer ();
    }

  /* Iterate through the lines of the comment */
  while (!had_eof)
    {
      /* Iterate through the characters on one line */
      while (!had_eof)
	{
	  CHECK_COM_SIZE;

	  switch (*buf_ptr)
	    {
	    case ' ':
	    case TAB:
	      /* If formatting, and previous break marker is
	         nonexistant, or before text on line, reset
	         it to here. */
	      if (format && line_break_ptr < text_on_line)
		line_break_ptr = e_com;

	      if (format)
		{
		  /* Don't write two spaces after another, unless the first space it preceeded by a dot. */
		  if (e_com == s_com || e_com[-1] != ' ' || e_com - 1 == s_com || e_com[-2] == '.')
		    {
		      *e_com++ = ' ';
		      column++;
		    }
		}
	      else if (*buf_ptr == ' ')
		{
		  *e_com++ = ' ';
		  column++;
		}
	      else
		{
		  /* Convert the tab to the appropriate number of spaces,
		     based on the column we found the comment in, not
		     the one we're printing in. */
		  int tab_width = (tabsize - ((column + found_column - start_column - 1) % tabsize));
		  column += tab_width;
		  while (tab_width--)
		    *e_com++ = ' ';
		}
	      break;

	    case EOL:
	      /* We may be at the end of a C++ comment */
	      if (comment_type == cplus_comment)
		{
		cplus_exit:
		  parser_state_tos->tos--;
		  parser_state_tos->com_col = (two_contiguous_comments ? 1 : start_column);
		  parser_state_tos->box_com = boxed_comment;
		  *e_com = 0;
		  return;
		}

	      if (format)
		{
		  /* Newline and null are the two characters which
		     end an input line, so check here if we need to
		     get the next line. */
		  if (*buf_ptr == EOL)
		    ++line_no;
		  buf_ptr++;
		  if (buf_ptr >= buf_end)
		    fill_buffer ();

		  /* If there are any spaces between the text and this
		     newline character, remove them. */
		  if (e_com > line_break_ptr && text_on_line < line_break_ptr)
		    e_com = line_break_ptr;

		  /* If this is "\n\n", or "\n<whitespace>\n",
		     it's a paragraph break. */
		  while (*buf_ptr == TAB || *buf_ptr == ' ')
		    if (++buf_ptr >= buf_end)
		      fill_buffer ();
		  if (*buf_ptr == EOL || !text_on_line)
		    {
		      paragraph_break = 1;
		      goto end_line;
		    }

		  /* Also need to eat the preamble. */
		  if (!boxed_comment && current_column () == found_column + 1 && buf_ptr[0] == '*' && buf_ptr[1] != '/')
		    {
		      if (++buf_ptr >= buf_end)
			fill_buffer ();
		      if (*buf_ptr == ' ' && ++buf_ptr >= buf_end)
			fill_buffer ();
		    }

		  /* This is a single newline.  Transform it (and any
		     following whitespace) into a single blank. */
		  if (e_com[-1] != ' ')
		    {
		      line_break_ptr = e_com;
		      *e_com++ = ' ';
		      column++;
		    }
		  continue;
		}

	      /* We are printing this line "as is", so output it
	         and continue on to the next line. */
	      goto end_line;

	    case '*':
	      /* Check if we've reached the end of the comment. */
	      if (comment_type == comment)
		{
		  if (*(buf_ptr + 1) == '/')
		    {
		      /* If it's not a boxed comment, put some whitespace
		         before the ending delimiter.  Otherwise, simply
		         insert the delimiter. */
		      if (!boxed_comment)
			{
			  if (text_on_line)
			    {
			      if (blankline_delims && !suppress_cdb)
				{
				  *e_com = '\0';
				  dump_line (true);
				  *e_com++ = ' ';
				}
			      else
				/* Insert space before closing delim */
			      if (*(e_com - 1) != ' ' && *(e_com - 1) != TAB)
				*e_com++ = ' ';
			    }
			  /* If no text on line, then line is completely empty
			     or starts with preamble, or is beginning of
			     comment and starts with beginning delimiter. */
			  else if (s_com == e_com || *s_com != '/')
			    {
			      e_com = s_com;
			      *e_com++ = ' ';
			    }
			  else
			    /* This is case of first comment line.  Test
			       with:
			       if (first_comment_line != com_lines)
			       abort (); */
			  if (*(e_com - 1) != ' ' && *(e_com - 1) != TAB)
			    *e_com++ = ' ';
			}

		      /* Now insert the ending delimiter */
		      *e_com++ = '*';
		      *e_com++ = '/';
		      *e_com = '\0';

		      /* Skip any whitespace following the comment.  If
		         there is only whitespace after it, print the line.

		         NOTE:  We're not printing the line: TRY IT! */
		      buf_ptr += 2;
		      while (*buf_ptr == ' ' || *buf_ptr == TAB)
			buf_ptr++;
		      if (buf_ptr >= buf_end)
			fill_buffer ();

		      parser_state_tos->tos--;
		      parser_state_tos->com_col = (two_contiguous_comments ? 1 : start_column);
		      parser_state_tos->box_com = boxed_comment;
		      return;
		    }

		  /* If this star is on the second line of the
		     comment in the same column as the star of the
		     beginning delimiter, then consider it
		     a boxed comment. */
		  if (first_comment_line == com_lines - 1 && e_com == s_com + line_preamble_length
		      && current_column () == found_column + 1)
		    {
		      /* Account for change in line_preamble_length: */
		      column -= line_preamble_length - 1;
		      line_preamble = " ";
		      line_preamble_length = 1;
		      boxed_comment = 1;
		      format = 0;
		      blankline_delims = 0;
		      *s_com = ' ';
		      *(s_com + 1) = '*';
		      text_on_line = e_com = s_com + 2;
		      column++;
		      break;
		    }
		}
	      /* If it was not the end of the comment, drop through
	         and insert the star on the line. */

	    default:
	      /* Some textual character. */
	      text_on_line = e_com;
	      *e_com++ = *buf_ptr;
	      column++;
	      break;
	    }


	  /* If we are formatting, check that we haven't exceeded the
	     line length.  If we haven't set line_break_ptr, keep going. */
	  if (format && column > right_margin && line_break_ptr)
	    {
	      if (line_break_ptr < e_com - 1)
		/* Here if we are really "breaking" the line:  the line
		   break is before some text we've seen. */
		{
		  *line_break_ptr = '\0';
		  save_ptr = line_break_ptr + 1;
		  save_length = e_com - save_ptr;
		  e_com = line_break_ptr;

		  /* If we had to go past `right_margin' to print stuff out,
		     extend `right_margin' out to this point. */
		  if ((column - save_length) > right_margin)
		    right_margin = column - save_length;
		}
	      else
		/* The line break is after the last text;  we're really
		   truncating the line. */
		{
		  if (comment_type == cplus_comment)
		    {
		      while (*buf_ptr == TAB || *buf_ptr == ' ')
			buf_ptr++;
		      buf_ptr--;
		      if (*buf_ptr == EOL)
			goto cplus_exit;
		    }
		  else
		    {
		      while (*buf_ptr == TAB || *buf_ptr == ' ' || *buf_ptr == EOL)
			buf_ptr++;

		      buf_ptr--;
		    }

		  *e_com = '\0';
		}
	      goto end_line;
	    }

	  if (*buf_ptr == EOL)
	    ++line_no;
	  buf_ptr++;
	  if (buf_ptr == buf_end)
	    fill_buffer ();
	}


    end_line:
      /* Compress pure whitespace lines into newlines. */
      if (!text_on_line && !visible_preamble && !(first_comment_line == com_lines))
	e_com = s_com;
      *e_com = '\0';
      dump_line (true);
      /* We're in the middle of a C-comment, don't add blank lines! */
      prefix_blankline_requested = 0;

      /* If formatting (paragraph_break is only used for formatted
         comments) and user wants blank lines merged, kill all white
         space after the "\n\n" indicating a paragraph break. */
      if (paragraph_break)
	{
	  if (merge_blank_comment_lines)
	    while (*buf_ptr == EOL || *buf_ptr == ' ' || *buf_ptr == TAB)
	      {
		if (*buf_ptr == EOL)
		  ++line_no;
		if (++buf_ptr >= buf_end)
		  fill_buffer ();
	      }
	  paragraph_break = 0;
	}
      else
	{
	  /* If it was a paragraph break (`if' clause), we scanned ahead
	     one character.  So, here in the `else' clause, advance buf_ptr. */
	  if (*buf_ptr == EOL)
	    ++line_no;
	  buf_ptr++;
	  if (buf_ptr >= buf_end)
	    fill_buffer ();
	}

    begin_line:
      if (had_eof)
	break;

      /* Indent the line properly.  If it's a boxed comment, align with
         the '*' in the beginning slash-star and start inserting there.
         Otherwise, insert blanks for alignment, or a star if the
         user specified -sc. */
      if (line_preamble)
	{
	  (void) memcpy (e_com, line_preamble, line_preamble_length);
	  e_com += line_preamble_length;
	  column = start_column + line_preamble_length;
	}
      else
	column = start_column;
      line_break_ptr = 0;

      /* If we have broken the line before the end for formatting,
         copy the text after the break onto the beginning of this
         new comment line. */
      if (save_ptr)
	{
	  while ((*save_ptr == ' ' || *save_ptr == TAB) && save_length)
	    {
	      save_ptr++;
	      save_length--;
	    }
	  (void) memcpy (e_com, save_ptr, save_length);
	  text_on_line = e_com;
	  e_com += save_length;
	  /* We only break if formatting, in which cases there
	     are no tabs, only spaces. */
	  column += save_length;
	  save_ptr = 0;
	  save_length = 0;
	}
      else
	{
	  while (*buf_ptr == ' ' || *buf_ptr == TAB)
	    if (++buf_ptr >= buf_end)
	      fill_buffer ();
	  text_on_line = 0;
	}
    }

  parser_state_tos->tos--;
  parser_state_tos->com_col = (two_contiguous_comments ? 1 : start_column);
  parser_state_tos->box_com = boxed_comment;
}
示例#11
0
/*
table_log()

trigger function for logging table changes

parameter:
  - log table name (optional)
return:
  - trigger data (for Pg)
*/
Datum table_log(PG_FUNCTION_ARGS) {
  TriggerData    *trigdata = (TriggerData *) fcinfo->context;
  int            ret;
  char           query[250 + NAMEDATALEN];	/* for getting table infos (250 chars (+ one times the length of all names) should be enough) */
  int            number_columns = 0;		/* counts the number columns in the table */
  int            number_columns_log = 0;	/* counts the number columns in the table */
  char           *orig_schema;
  char           *log_schema;
  char           *log_table;
  int            use_session_user = 0;          /* should we write the current (session) user to the log table? */

  /*
   * Some checks first...
   */

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "start table_log()");
#endif /* TABLE_LOG_DEBUG */

  /* called by trigger manager? */
  if (!CALLED_AS_TRIGGER(fcinfo)) {
    elog(ERROR, "table_log: not fired by trigger manager");
  }

  /* must only be called for ROW trigger */
  if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) {
    elog(ERROR, "table_log: can't process STATEMENT events");
  }

  /* must only be called AFTER */
  if (TRIGGER_FIRED_BEFORE(trigdata->tg_event)) {
    elog(ERROR, "table_log: must be fired after event");
  }

  /* now connect to SPI manager */
  ret = SPI_connect();
  if (ret != SPI_OK_CONNECT) {
    elog(ERROR, "table_log: SPI_connect returned %d", ret);
  }

  /* get schema name for the table, in case we need it later */
  orig_schema = get_namespace_name(RelationGetNamespace(trigdata->tg_relation));

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "prechecks done, now getting original table attributes");
#endif /* TABLE_LOG_DEBUG */

  number_columns = count_columns(trigdata->tg_relation->rd_att);
  if (number_columns < 1) {
    elog(ERROR, "table_log: number of columns in table is < 1, can this happen?");
  }
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "number columns in orig table: %i", number_columns);
#endif /* TABLE_LOG_DEBUG */

  if (trigdata->tg_trigger->tgnargs > 3) {
    elog(ERROR, "table_log: too many arguments to trigger");
  }
  
  /* name of the log schema */
  if (trigdata->tg_trigger->tgnargs > 2) {
    /* check if a log schema argument is given, if yes, use it */
    log_schema = trigdata->tg_trigger->tgargs[2];
  } else {
    /* if no, use orig_schema */
    log_schema = orig_schema;
  }

  /* should we write the current user? */
  if (trigdata->tg_trigger->tgnargs > 1) {
    /* check if a second argument is given */  
    /* if yes, use it, if it is true */
    if (atoi(trigdata->tg_trigger->tgargs[1]) == 1) {
      use_session_user = 1;
#ifdef TABLE_LOG_DEBUG
      elog(NOTICE, "will write session user to 'trigger_user'");
#endif /* TABLE_LOG_DEBUG */
    }
  }

  /* name of the log table */
  if (trigdata->tg_trigger->tgnargs > 0) {
    /* check if a logtable argument is given */  
    /* if yes, use it */
    log_table = (char *) palloc((strlen(trigdata->tg_trigger->tgargs[0]) + 2) * sizeof(char));
    sprintf(log_table, "%s", trigdata->tg_trigger->tgargs[0]);
  } else {
    /* if no, use 'table name' + '_log' */
    log_table = (char *) palloc((strlen(do_quote_ident(SPI_getrelname(trigdata->tg_relation))) + 5) * sizeof(char));
    sprintf(log_table, "%s_log", SPI_getrelname(trigdata->tg_relation));
  }

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "log table: %s", log_table);
#endif /* TABLE_LOG_DEBUG */

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "now check, if log table exists");
#endif /* TABLE_LOG_DEBUG */

  /* get the number columns in the table */
  snprintf(query, 249, "%s.%s", do_quote_ident(log_schema), do_quote_ident(log_table));
  number_columns_log = count_columns(RelationNameGetTupleDesc(query));
  if (number_columns_log < 1) {
    elog(ERROR, "could not get number columns in relation %s", log_table);
  }
#ifdef TABLE_LOG_DEBUG
    elog(NOTICE, "number columns in log table: %i", number_columns_log);
#endif /* TABLE_LOG_DEBUG */

  /* check if the logtable has 3 (or now 4) columns more than our table */
  /* +1 if we should write the session user */
  if (use_session_user == 0) {
    /* without session user */
    if (number_columns_log != number_columns + 3 && number_columns_log != number_columns + 4) {
      elog(ERROR, "number colums in relation %s(%d) does not match columns in %s(%d)", SPI_getrelname(trigdata->tg_relation), number_columns, log_table, number_columns_log);
    }
  } else {
    /* with session user */
    if (number_columns_log != number_columns + 3 + 1 && number_columns_log != number_columns + 4 + 1) {
      elog(ERROR, "number colums in relation %s does not match columns in %s", SPI_getrelname(trigdata->tg_relation), log_table);
    }
  }
#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "log table OK");
#endif /* TABLE_LOG_DEBUG */


  /* For each column in key ... */

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "copy data ...");
#endif /* TABLE_LOG_DEBUG */
  if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) {
    /* trigger called from INSERT */
#ifdef TABLE_LOG_DEBUG
    elog(NOTICE, "mode: INSERT -> new");
#endif /* TABLE_LOG_DEBUG */
    __table_log(trigdata, "INSERT", "new", trigdata->tg_trigtuple, number_columns, log_table, use_session_user, log_schema);
  } else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) {
    /* trigger called from UPDATE */
#ifdef TABLE_LOG_DEBUG
    elog(NOTICE, "mode: UPDATE -> old");
#endif /* TABLE_LOG_DEBUG */
    __table_log(trigdata, "UPDATE", "old", trigdata->tg_trigtuple, number_columns, log_table, use_session_user, log_schema);
#ifdef TABLE_LOG_DEBUG
    elog(NOTICE, "mode: UPDATE -> new");
#endif /* TABLE_LOG_DEBUG */
    __table_log(trigdata, "UPDATE", "new", trigdata->tg_newtuple, number_columns, log_table, use_session_user, log_schema);
  } else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) {
    /* trigger called from DELETE */
#ifdef TABLE_LOG_DEBUG
    elog(NOTICE, "mode: DELETE -> old");
#endif /* TABLE_LOG_DEBUG */
    __table_log(trigdata, "DELETE", "old", trigdata->tg_trigtuple, number_columns, log_table, use_session_user, log_schema);
  } else {
    elog(ERROR, "trigger fired by unknown event");
  }

#ifdef TABLE_LOG_DEBUG
  elog(NOTICE, "cleanup, trigger done");
#endif /* TABLE_LOG_DEBUG */
  /* clean up */
  pfree(log_table);

  /* close SPI connection */
  SPI_finish();
  /* return trigger data */
  return PointerGetDatum(trigdata->tg_trigtuple);
}
示例#12
0
int main(int argc, char* argv[]){
	if(argc < 2){
		std::cout << " Error: Invalid number of arguments to " << argv[0] << ". Expected 1, received " << argc-1 << ".\n";
		help(argv[0]);
		return 1;
	}

	std::vector<int> skip_lines;
	bool use_column_names = false;
	int index = 2;
	int num_head_lines = 0;
	int last_skip_line = -9999;
	char delimiter = '\t';
	while(index < argc){
		if(strcmp(argv[index], "--names") == 0){
			std::cout << " Using first line of data for column names\n";
			use_column_names = true;
		}
		else if(strcmp(argv[index], "--header") == 0){
			if(index + 1 >= argc){
				std::cout << " Error! Missing required argument to '--header'!\n";
				help(argv[0]);
				return 1;
			}
			num_head_lines = atoi(argv[++index]);
			std::cout << " Using file header of " << num_head_lines << " lines\n";
		}
		else if(strcmp(argv[index], "--delimiter") == 0){
			if(index + 1 >= argc){
				std::cout << " Error! Missing required argument to '--delimiter'!\n";
				help(argv[0]);
				return 1;
			}
			delimiter = (char)atoi(argv[++index]);
			std::cout << " Using column delimiter '" << delimiter << "'\n";
		}
		else if(strcmp(argv[index], "--skip") == 0){
			if(index + 1 >= argc){
				std::cout << " Error! Missing required argument to '--skip'!\n";
				help(argv[0]);
				return 1;
			}
			int num_lines_to_skip = atoi(argv[++index]);
			std::cout << " Skipping " << num_lines_to_skip << " lines in the data file\n";
			if(index + num_lines_to_skip >= argc){
				std::cout << " Error! Missing required argument to '--skip'!\n";
				help(argv[0]);
				return 1;
			}
			int temp_line;
			for(int i = 0; i < num_lines_to_skip; i++){
				temp_line = atoi(argv[++index]);
				skip_lines.push_back(temp_line);
				if(temp_line > last_skip_line){ last_skip_line = temp_line; }
			}
		}
		else{ 
			std::cout << " Error! Unrecognized option '" << argv[index] << "'!\n";
			help(argv[0]);
			return 1;
		}
		index++;
	}

	std::ifstream input_file(argv[1]);
	if(!input_file.good()){
		std::cout << " Error: Failed to open input file " << argv[1] << std::endl;
		return 1;
	}

	std::string fname = get_name(argv[1]);
	TFile *output_file = new TFile((fname+".root").c_str(),"RECREATE");
	if(!output_file->IsOpen()){
		std::cout << " Error: Failed to open output file " << fname << ".root\n";
		input_file.close();
		output_file->Close();
		return 1;
	}
	
	TTree *tree = new TTree("data","Raw2Root Tree");
	int count = 0;
	int num_columns = 0;
	
	output_file->cd();

	std::vector<std::string> names;
	std::vector<std::string> titles;
	std::string first_line;
	if(num_head_lines > 0){
		for(int i = 0; i < num_head_lines; i++){
			std::getline(input_file, first_line);
			if(input_file.eof() || !input_file.good()){
				input_file.close();
				output_file->Close();
				return 1;
			}
			if(is_in(skip_lines, ++count)){ continue; }
			
			size_t index = first_line.find(delimiter);
			if(index != std::string::npos){
				names.push_back(first_line.substr(0, index));
				titles.push_back(first_line.substr(index+1));
			}
			else{ 
				std::stringstream stream;
				if(i < 9){ stream << "line00" << i+1; }
				else if(i < 99){ stream << "line0" << i+1; }
				else{ stream << "line" << i+1; }
				names.push_back(stream.str());
				titles.push_back(first_line);
			}
		}
	}

	/*for(int i = 0; i < names.size(); i++){
		char *cstr1 = new char[names[i].length()+1];
		for(int j = 0; j < names[i].length(); j++){
			cstr1[j] = names[i].at(j);
			//std::cout << names[i][j] << "\t" << cstr1[j] << std::endl;
		}
		cstr1[names[i].length()] = '\0';
		std::cout << names[i].length() << "\t" << strlen(cstr1) << std::endl;
		printf("cstr1: %s\n", cstr1);
		char *cstr2 = new char[titles[i].length()+1];
		for(int j = 0; j < titles[i].length(); j++){
			cstr2[j] = titles[i][j];
		}
		cstr2[titles[i].length()] = '\0';
		delete[] cstr1;
		delete[] cstr2;
	}*/

	// Get the number of columns
	std::getline(input_file, first_line);
	if(input_file.eof() || !input_file.good()){
		input_file.close();
		output_file->Close();
		return 1;
	}

	std::vector<std::string> column_names;
	num_columns = count_columns(first_line, column_names, delimiter);
	std::cout << " Found " << num_columns << " columns of data\n";
	std::string bname;

	float *vars = new float[num_columns];
	for(int i = 0; i < num_columns; i++){
		vars[i] = 0.0;
	}

	if(!use_column_names){	
		input_file.seekg(-first_line.size(), std::ios::cur);
		for(int i = 0; i < num_columns; i++){
			std::stringstream stream;
			if(i < 10){ stream << "Col0" << i; }
			else{ stream << "Col" << i; }
			tree->Branch(stream.str().c_str(),&vars[i]);
		}
	}
	else{ // Extract column names from data
		for(int i = 0; i < num_columns; i++){
			tree->Branch(column_names[i].c_str(),&vars[i]);
		}
	}

	while(true){
		// Get a line of data
		if(count % 10000 == 0 && count != 0){ std::cout << "  Line " << count << " of data file\n"; }
		if(count+1 <= last_skip_line && is_in(skip_lines, ++count)){ continue; }
		
		for(int i = 0; i < num_columns; i++){
			input_file >> vars[i];
		}

		if(input_file.eof() || !input_file.good()){ break; }
		
		// Fill all branches
		tree->Fill();
		count++;
	}

	output_file->cd();
	TNamed *named = new TNamed();
	std::vector<std::string>::iterator iter1, iter2;
	for(iter1 = names.begin(), iter2 = titles.begin(); iter1 != names.end() && iter2 != titles.end(); iter1++, iter2++){
		named->SetNameTitle(iter1->c_str(), iter2->c_str());
		named->Write();
	}
	
	tree->Write();
	
	std::cout << " Found " << count << " entries in " << num_columns << " columns\n";
	std::cout << " Generated file " << fname << ".root\n";

	input_file.close();
	output_file->Close();

	delete[] vars;

	return 0;
}
示例#13
0
int parse_config(FILE *cnf, ode_model_parameters *omp, main_options *cnf_options){
  /* This function parses the configuration file The configuration
   * file contains xml like expressions containing data, measurement
   * time points, etc.
   * We start by defining regular expressions for the field names
   * 
   */
  int D=0,U=0,C=0,F=0,T=0,N=0;
  int i,l;
  int n=10; // number of fields
  regex_t cpt[2*n]; // defines the patterns for the field names
  regex_t comment;
  int bsize=2048;
  char buffer[bsize];
  gsl_matrix *reference_data;
  gsl_matrix *sd_reference_data;
  omp->data_is_relative=0; // assume data to be absolute
  char *var_value, *var_value_newline;

  //comments in file
  regcomp(&comment,"#|//|%",REG_EXTENDED);

  regcomp(&cpt[0],"\\[time\\]",REG_EXTENDED);
  regcomp(&cpt[1],"\\[reference_input\\]",REG_EXTENDED);
  regcomp(&cpt[2],"\\[reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[3],"\\[sd_reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[4],"\\[input\\]",REG_EXTENDED);
  regcomp(&cpt[5],"\\[data\\]",REG_EXTENDED);
  regcomp(&cpt[6],"\\[sd_data\\]",REG_EXTENDED);
  regcomp(&cpt[7],"\\[prior_mu\\]",REG_EXTENDED);
  regcomp(&cpt[8],"\\[prior_inv(erse)?_cov(ariance)?\\]",REG_EXTENDED);
  regcomp(&cpt[9],"\\[output\\]",REG_EXTENDED);

  regcomp(&cpt[n+0],"\\[/time\\]",REG_EXTENDED);
  regcomp(&cpt[n+1],"\\[/reference_input\\]",REG_EXTENDED);
  regcomp(&cpt[n+2],"\\[/reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[n+3],"\\[/sd_reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[n+4],"\\[/input\\]",REG_EXTENDED);
  regcomp(&cpt[n+5],"\\[/data\\]",REG_EXTENDED);
  regcomp(&cpt[n+6],"\\[/sd_data\\]",REG_EXTENDED);
  regcomp(&cpt[n+7],"\\[/prior_mu\\]",REG_EXTENDED);
  regcomp(&cpt[n+8],"\\[/prior_inv(erse)?_cov(ariance)?\\]",REG_EXTENDED);
  regcomp(&cpt[n+9],"\\[/output\\]",REG_EXTENDED);

  /* now that we have several regular expressions, we parse the file
   * once to get the problem size: D,P,F,U,C; then we allocate mamory
   * and parse the file a second time to read the data, inputs and so
   * forth.
   */


  /* relevant interfaces:
   * count_rows(FILE *cnf, regex_t *end, regex_t *comment)
   * count_columns(const char *c)
   * read_columns(char *c, double *vector, const int length)
   * read_block(int rows, int columns, FILE *f, double *target, regex_t *comment)
   */

  while (!feof(cnf)){
    do fgets(buffer,bsize,cnf);
    while (regexec(&comment,buffer,0,NULL,0)==0);
    var_value=strchr(buffer,'='); // string looks like this: [var_name]=[var_value]
    if (var_value!=NULL) { // we have a variable definition
      var_value[0]='\0'; //mark the end of the variable name
      /*printf("var_name=%s\n",buffer);
        printf("var_value=%s\n",var_value+1);
       *printf("removing newline....\n");
       */
      var_value_newline=strchr(++var_value,'\n');
      if (var_value_newline!=NULL) var_value_newline[0]='\0';      
      printf("# [cfg] {%s} ← {%s}\n",buffer,var_value);
      
      if (strcmp(cnf_options->output_file,"sample.dat")==0 && strcmp(buffer,"output")==0) strcpy(cnf_options->output_file,var_value);
      else if (cnf_options->sample_size<0 && strcmp(buffer,"sample_size")==0) cnf_options->sample_size=strtol(var_value,NULL,0);
      else if (cnf_options->target_acceptance<0 && strcmp(buffer,"acceptance")==0) cnf_options->target_acceptance=strtod(var_value,NULL);
      else if (cnf_options->initial_stepsize<0 && strcmp(buffer,"step_size")==0) cnf_options->initial_stepsize=strtod(var_value,NULL);
      else if (strcmp(buffer,"t0")==0) {omp->t0=strtod(var_value,NULL); printf("# t0 = %f\n",omp->t0);}
    }
    else { 
      for (i=0;i<n;i++){
	if (regexec(&cpt[i],buffer,0,NULL,0)==0){
	  /* printf("found match with regular expression %i.\n",i); */
	  /* printf(buffer); */
	  switch (i){ // counting columns and/or rows
	  case 0: /*time*/
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    T=count_rows(cnf, &cpt[n+i], &comment);
	    break;
	  case 1: /* reference input */
	    omp->data_is_relative=1;
	    printf("data is relative.\n");
	    break;
	  case 4: /* inputs */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    U=count_columns(buffer);
	    C=count_rows(cnf, &cpt[n+i], &comment);
	    //	  printf("# input field has %i lines. (%i experimental conditions)\n",l,C);
	    break;
	  case 5: /* data */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    F=count_columns(buffer);
	    l=count_rows(cnf, &cpt[n+i], &comment);
	    printf("# data has %i (%i × %i) lines.\n",l,C,T);
	    break;
	  case 7: /* problem size */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    D=count_rows(cnf, &cpt[n+i], &comment);
	    break;
	  case 9: /* output structure */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    N=count_columns(buffer);
	    F=count_rows(cnf, &cpt[n+i], &comment);
	  }// switch
	  break;
	}// if match
      }// for (regular expressions)
    }// while !EOF
  }
  printf("# file read once to determine the size of data and inputs.\n");
  printf("# D=%i\tN=%i\tF=%i\tU=%i\tC=%i\tT=%i\n",D,N,F,U,C,T);
  omp->D=D;
  /* now we must allocate the necessary memory and fill it with values
   */
  ode_model_parameters_alloc(omp, D, N, F, T, U, C);
  reference_data=gsl_matrix_alloc(T,F);
  sd_reference_data=gsl_matrix_alloc(T,F);
  printf("# memory allocated.\n");
  /* we reset the FILE structure and parse again, now reading the
   * values.
   */
  rewind(cnf);
  printf("# rewind.\n");
  while (!feof(cnf)){
    do fgets(buffer,bsize,cnf);
    while (regexec(&comment,buffer,0,NULL,0)==0);
    for (i=0;i<n;i++){
      if (    regexec(&cpt[i],buffer,0,NULL,0)==0){
        /* printf("found match with regular expression %i.\n",i); */
        /* printf(buffer); */
	switch (i){// reading the data
	case 0: /*time*/
	  read_block(T,1,cnf,omp->t->data,&comment);
	  printf("# measurement time(s) read.\n");
	  break;
	case 1: /* reference input */
	  //printf("# reading reference input.\n");
	  read_block(1,U,cnf,omp->reference_u->data,&comment);
	  printf("# reference input read.\n");
	  break;
	case 2: /* reference data */
	  read_block(T,F,cnf,reference_data->data,&comment);
	  printf("# reference data read.\n");
	  break;
	case 3: /* sd reference data */
	  read_block(T,F,cnf,sd_reference_data->data,&comment);
	  printf("# standard deviation of reference data read.\n");
	  break;
	case 4: /* inputs */
	  read_block(C,U,cnf,omp->input_u->data,&comment);
	  printf("# input read.\n");
	  break;
	case 5: /* data */
	  read_block(C*T,F,cnf,omp->Data->data,&comment);
	  printf("# data read.\n");
	  break;
	case 6: /* sd data */
	  read_block(C*T,F,cnf,omp->sdData->data,&comment);
	  printf("# standard deviation of data read.\n");
	  break;
	case 7:
	  read_block(D,1,cnf,omp->prior_mu->data,&comment);
	  printf("# prior mean read.\n");
	  break;
	case 8: /* prior inverse covariance */
	  read_block(D,D,cnf,omp->prior_inverse_cov->data,&comment);
	  printf("# prior inverse covariance matrix read.\n");
	  break;
	case 9: /* output structure */
	  read_block(F,N,cnf,omp->output_C->data,&comment);
	}// switch
	break;
      }// if match
    }// for (regular expressions)
  }// while !EOF
  printf("# configuration read.\n");
  /* now we take the ratios of data and reference data
   */

  if (omp->data_is_relative){
    printf("# calculating relative data (ratios)...");
    ratio_with_sd(omp->Data,omp->sdData,reference_data,sd_reference_data);
    printf("# done.\n");
  }

  //  omp->t0=0.0;

  // cleanup
  gsl_matrix_free(reference_data);
  gsl_matrix_free(sd_reference_data);
  for (i=0;i<2*n;i++)  regfree(&cpt[i]);

  return EXIT_SUCCESS;
}