/* * 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); }
// 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; }