Пример #1
0
/* 
 * John M. suggests:
 * You might want to add four more:
 *
 * _ohdraw_ (optional head-end arrow for edges)
 * _ohldraw_ (optional head-end label for edges)
 * _otdraw_ (optional tail-end arrow for edges)
 * _otldraw_ (optional tail-end label for edges)
 * 
 * that would be generated when an additional option is supplied to 
 * dot, etc. and 
 * these would be the arrow/label positions to use if a user want to flip the 
 * direction of an edge (as sometimes is there want).
 * 
 * N.B. John M. asks:
 *   By the way, I don't know if you ever plan to add other letters for 
 * the xdot spec, but could you reserve "a" and also "A" (for  attribute), 
 * "n" and also "N" (for numeric), "w" (for sWitch),  "s" (for string) 
 * and "t" (for tooltip) and "x" (for position). We use  those letters in 
 * our drawing spec (and also "<" and ">"), so if you  start generating 
 * output with them, it could break what we have. 
 */
void extend_attrs(GVJ_t * job, graph_t *g, int s_arrows, int e_arrows)
{
    node_t *n;
    edge_t *e;
    attrsym_t *n_draw = NULL;
    attrsym_t *n_l_draw = NULL;
    attrsym_t *e_draw = NULL;
    attrsym_t *h_draw = NULL;
    attrsym_t *t_draw = NULL;
    attrsym_t *e_l_draw = NULL;
    attrsym_t *hl_draw = NULL;
    attrsym_t *tl_draw = NULL;
    unsigned char buf0[BUFSIZ];
    unsigned char buf1[BUFSIZ];
    unsigned char buf2[BUFSIZ];
    unsigned char buf3[BUFSIZ];
    unsigned char buf4[BUFSIZ];
    unsigned char buf5[BUFSIZ];

    gvc = job->gvc;

    agsafeset (g, "xdotversion", XDOTVERSION, "");
    if (GD_has_labels(g) & GRAPH_LABEL)
	g_l_draw = safe_dcl(g, g, "_ldraw_", "", agraphattr);
    else
	g_l_draw = NULL;
    if (GD_n_cluster(g))
	g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
    else
	g_draw = NULL;

    n_draw = safe_dcl(g, g->proto->n, "_draw_", "", agnodeattr);
    n_l_draw = safe_dcl(g, g->proto->n, "_ldraw_", "", agnodeattr);

    e_draw = safe_dcl(g, g->proto->e, "_draw_", "", agedgeattr);
    if (e_arrows)
	h_draw = safe_dcl(g, g->proto->e, "_hdraw_", "", agedgeattr);
    if (s_arrows)
	t_draw = safe_dcl(g, g->proto->e, "_tdraw_", "", agedgeattr);
    if (GD_has_labels(g) & EDGE_LABEL)
	e_l_draw = safe_dcl(g, g->proto->e, "_ldraw_", "", agedgeattr);
    if (GD_has_labels(g) & HEAD_LABEL)
	hl_draw = safe_dcl(g, g->proto->e, "_hldraw_", "", agedgeattr);
    if (GD_has_labels(g) & TAIL_LABEL)
	tl_draw = safe_dcl(g, g->proto->e, "_tldraw_", "", agedgeattr);

    agxbinit(&xbuf0, BUFSIZ, buf0);
    agxbinit(&xbuf1, BUFSIZ, buf1);
    agxbinit(&xbuf2, BUFSIZ, buf2);
    agxbinit(&xbuf3, BUFSIZ, buf3);
    agxbinit(&xbuf4, BUFSIZ, buf4);
    agxbinit(&xbuf5, BUFSIZ, buf5);

    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (ND_shape(n) && !isInvis(late_string(n, N_style, ""))) {
	    ND_shape(n)->fns->codefn(job, n);
	    agxset(n, n_draw->index, agxbuse(xbufs[EMIT_NDRAW]));
	    agxset(n, n_l_draw->index, agxbuse(xbufs[EMIT_NLABEL]));
	}
	if (State < GVSPLINES)
	    continue;
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    if (ED_edge_type(e) == IGNORED)
		continue;
	    if (isInvis(late_string(e, E_style, "")))
		continue;
	    if (ED_spl(e) == NULL)
		continue;

	    emit_edge_graphics (job, e);
	    agxset(e, e_draw->index, agxbuse(xbufs[EMIT_EDRAW]));
	    if (t_draw) agxset(e, t_draw->index, agxbuse(xbufs[EMIT_TDRAW]));
	    if (h_draw) agxset(e, h_draw->index, agxbuse(xbufs[EMIT_HDRAW]));
	    if (e_l_draw) agxset(e, e_l_draw->index,agxbuse(xbufs[EMIT_ELABEL]));
	    if (tl_draw) agxset(e, tl_draw->index, agxbuse(xbufs[EMIT_TLABEL]));
	    if (hl_draw) agxset(e, hl_draw->index, agxbuse(xbufs[EMIT_HLABEL]));
	}
    }
  
    emit_background(job, g);
    if (agxblen(xbufs[EMIT_GDRAW])) {
	if (!g_draw)
	    g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
	agxset(g, g_draw->index, agxbuse(xbufs[EMIT_GDRAW]));
    }
    if (GD_label(g)) {
	emit_label(job, EMIT_GLABEL, GD_label(g), (void *) g);
	agxset(g, g_l_draw->index, agxbuse(xbufs[EMIT_GLABEL]));
    }
    emit_clusters(job, g, 0);
    agxbfree(&xbuf0);
    agxbfree(&xbuf1);
    agxbfree(&xbuf2);
    agxbfree(&xbuf3);
    agxbfree(&xbuf4);
    agxbfree(&xbuf5);
}
Пример #2
0
// This method will read the input file char by char
//   and will clean the input and build the lexTable
int execute( ){
  // open input.txt and cleaninput.txt
	FILE *input = fopen( "input.txt","r" );
	FILE *clean = fopen( "cleaninput.txt","w+" );

  // begin grabbing char by char
	char c = getc( input );
  buffer = (char *)malloc(13);

  // while there are characters left parse the file
	while( c != EOF ){    
		// makes sure the buffer is clean
    for( temp = 0; temp < 13; temp++ )
      buffer[temp] = '\0';
		
    // start building a word
    buffer[bufferLen] = c;

		if( isLetter(c) ){	// word starts with a letter

      // keep adding letters or digits to the word
      while( isLetter(c) || isDigit(c) ){
				buffer[bufferLen++] = c;
        // if the buffer word is too large give error
        if( bufferLen > 11 ) return error( input, clean, c, buffer, 2 );

				c = getc( input );
			}
      // now check if the found word is a reserved word
      if( !isReserved( clean, buffer ) )
        // add to lexTable as an identsym
        addToTable( clean, buffer, identsym );

      // unget one char
			ungetc( c, input );

		}else if( isDigit(c) ){ // word start with a digit 
      
      // keep adding digits to the word (number)
			while( isDigit(c) ){
				buffer[bufferLen++] = c;
        // if the buffer word (number) is no large give error
        if( bufferLen > 5 ) return error( input, clean, c, buffer, 1 );

				c = getc( input );
        // if the word starts with a digit and has a letter give error
        if( isLetter(c) ) return error( input, clean, c, buffer, 0 );

			}
      // add to lexTable as an numbersym
      addToTable( clean, buffer, numbersym );
 
      // unget one char and add buffer to cleaninput.txt
			ungetc( c, input );
			
		}else if( isSymbol(c) ){ // word is a symbol
			// use a switch to add the corresponding symbol to the lexTable	
      //   also add the symbol to cleaninput.txt
			switch(c){
      case '+':
        addToTable( clean, "+", plussym );
        break;
      case '-':
        addToTable( clean, "-", minussym );
        break;
      case '*':
        addToTable( clean, "*", multsym );
        break;   
      case '/': // two comment formatts that are left out of cleaninput.txt
				c = getc( input );
        switch(c){
        case '*': // '/*' multiline comment
          do{ // waits for another '/' after a '*'
						do{ // waits for another '*'
							c = getc( input ); 
						}while( c != '*' );
						c = getc( input );
					}while( c != '/' );
          break;

        case '/': // '//' singleline comment
          do{ // waits for a newline character
            c = getc( input );
          }while( c != NEWLINE );
          break;

        default: // '/' as in 'divides' add this one to the table
          addToTable( clean, "/", slashsym );
          ungetc( c, input );
        }
				break;
      case '(':
        addToTable( clean, "(", lparentsym );
        break;
      case ')':
        addToTable( clean, ")", rparentsym );
        break;
      case '=':
        addToTable( clean, "=", eqlsym );
        break;
      case ',':
        addToTable( clean, ",", commasym );
        break;
	    case '.':
        addToTable( clean, ".", periodsym );
        break;
	    case '<': 
        c = buffer[++bufferLen] = getc( input );
        switch( c ){
        case '=': // less than or equal to
          addToTable( clean, "<=", leqsym );
          break;
        case '>': // '<>' neqsym
          addToTable( clean, "<>", neqsym );
          break;
        default: // just less than
          addToTable( clean, "<", lessym );
        } 
//        ungetc( c, input );
        break;
	    case '>': 
        c = buffer[++bufferLen] = getc( input );
        switch( c ){
        case '=': // greater than or equal to
          addToTable( clean, ">=", leqsym );
          break;
        default: // just greater than
          addToTable( clean, ">", lessym );
        } 
        ungetc( c, input );
        break;
      case ';':
        addToTable( clean, ";", semicolonsym );
        break;
	    case ':': // a colon is found check for an '=' 
        // if not bleed into the default case to send an error
        buffer[++bufferLen] = getc( input );
        if( !strncmp( buffer, ":=", 2 ) ){
          addToTable( clean, ":=", becomessym );
          break;
        }
			default:
       return error( input, clean, c, buffer, 3 );
			}
		}else if( isInvis(c) ){ // word is a white space
			// add the char to the buffer
      while( isInvis(c) ){
        buffer[0] = c;
        c = getc( input ); 
      }
      ungetc( c, input );
			fprintf( clean, "%s", buffer );
		}else
      return error( input, clean, c, buffer, 3 );

    // reset bufferLen and continue building char by char
		bufferLen = 0;
		c = getc( input );
	}
	fclose( input );
  fclose( clean );
  return 1;
}