qdoc.cpp
/* \file qdoc.cpp * */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <iostream> #include <string> using namespace std; #include "strtoken.h" const int MAX_FILES = 32; //! documents Quartus Verilog projects class qdoc { public: qdoc() { }; ~qdoc() { }; void read_qsf(FILE *in); void read_cfg(FILE *in, FILE *out); void parse_insert(char *str, FILE *out); void print(); void verilog_contents(FILE *out); void quartus_contents(FILE *out); void swap_toplevel(); void verilog_print(FILE *out, string filename); void quartus_print(FILE *out, string suffix); string projname; string family,device,date,quartus_version; string toplevel; string verilog_file[MAX_FILES]; string quartus_file[MAX_FILES]; int nfiles, nqfiles; }; void transcribe(FILE *in, FILE *out); int main(int argc, char *argv[]) { qdoc doc; FILE *in, *out; errno_t nerr; if (argc<2) { cout << "usage: qdoc projname [config_file]\n"; cout << "default config_file is \"qdoc.cfg.html\"\n"; return EXIT_FAILURE; } // open project qsf file doc.projname = argv[1]; string filename = doc.projname + ".qsf"; nerr = fopen_s(&in,filename.c_str(),"r"); if (nerr) { cout << "file: " << filename << " not found\n"; return EXIT_FAILURE; } doc.read_qsf(in); doc.swap_toplevel(); fclose(in); // open output configuration file filename = (argc>2? argv[2]: "qdoc.cfg.html"); nerr = fopen_s(&in,filename.c_str(),"r"); if (nerr) { cout << "file: " << filename << " not found\n"; return EXIT_FAILURE; } // open output file filename = doc.projname + ".html"; nerr = fopen_s(&out,filename.c_str(),"w"); if (nerr) { cout << "error opening " << filename << endl; } doc.read_cfg(in, out); fclose(in); fclose(out); doc.print(); return EXIT_SUCCESS; } void qdoc::read_qsf(FILE *in) { char buf[512]; char *inp, *token; bool done = false; int lines = 0; nfiles = 0; while (!done) { fgets(buf,511,in); if (feof(in)) return; lines++; strtrm(buf,'\n'); // terminate at newline character strtrm(buf,'#'); // terminate at comment character inp = buf; string tok; int state = 0; while ((token=strtoken(inp,' '))!=0) { tok = token; if (state==0) { if (tok.compare("set_global_assignment")!=0) break; state = 1; } else if (state==1) { if (tok.compare("-name")!=0) break; state = 2; } else if (state==2) { strqtrm(inp,' '); if (!inp) break; if (tok.compare("FAMILY")==0) family = inp; else if (tok.compare("DEVICE")==0) device = inp; else if (tok.compare("TOP_LEVEL_ENTITY")==0) toplevel = inp; else if (tok.compare("PROJECT_CREATION_TIME_DATE")==0) date = inp; else if (tok.compare("LAST_QUARTUS_VERSION")==0) quartus_version = inp; else if (tok.compare("VERILOG_FILE")==0) verilog_file[nfiles++] = inp; state = 0; break; } } } } void qdoc::swap_toplevel() { string filename = toplevel + ".v"; int found = -1; for (int i=0; i<nfiles; i++) { if (filename.compare(verilog_file[i])==0) { found = i; break; } } if (found) { string tmp = verilog_file[0]; verilog_file[0] = verilog_file[found]; verilog_file[found] = tmp; } } void qdoc::print() { cout << "Family: " << family << endl; cout << "Device: " << device << endl; cout << "Quartus "<< quartus_version << endl; cout << "date " << date << endl; cout << "top level entity " << toplevel << endl; if (nfiles) cout << nfiles << " verilog files\n"; if (nqfiles) cout << nqfiles << " quartus files\n"; } void qdoc::verilog_contents(FILE *out) { for (int i=0; i<nfiles; i++) { fputs("<a href=\"#",out); fputs(verilog_file[i].c_str(),out); fputs("\">",out); fputs(verilog_file[i].c_str(),out); fputs("</a><br>\n",out); } } void qdoc::verilog_print(FILE *out, string filename) { FILE *in; errno_t nerr = fopen_s(&in,filename.c_str(),"r"); if (nerr) { cout << "file not found: " << filename << endl; return; } fputs("<a name=\"",out); fputs(filename.c_str(),out); fputs("\">\n\n",out); fputs("<h3><code>",out); fputs(filename.c_str(),out); fputs("</code></h3>\n",out); transcribe(in,out); fclose(in); } void qdoc::read_cfg(FILE *in, FILE *out) { char buf[512]; char *inp, *next, *html; bool done = false; nqfiles = 0; /* * Go through input file, line by line */ while (!done) { fgets(buf,511,in); if (feof(in)) break; next = buf; /* * parse current line */ while (next) { /* * search for '<', and copy prior text to * output stream */ inp = next; next = strqtrm(inp,'<'); if (*inp) fputs(inp,out); /* * next points to character after '<' (if '<' * was found). */ if (next) { /* * isolate (in html) text up to the character '>' */ html = next; next = strqtrm(html,'>'); /* * check for known codes */ string token = html; char *value = strqtrm(html,' '); if (token.substr(0,7).compare("include")==0) { quartus_file[nqfiles++] = value; //cout << "quartus_file: " << quartus_file[nqfiles-1] << endl; continue; // go to next line } else if (token.substr(0,6).compare("insert")==0) { parse_insert(value,out); } /* * otherwise just echo the html code */ else fprintf(out,"<%s>",token.c_str()); } } } } void insert_date(FILE *out) { char buf[32]; time_t ltime; errno_t nerr; time( <ime ); nerr = ctime_s(buf,30,<ime); int nchar = strlen(buf); buf[nchar-1] = 0; fputs(buf,out); } void qdoc::parse_insert(char *str, FILE *out) { string tok = str; //strtoken(str,' '); if (tok.compare("projname")==0) fputs(projname.c_str(),out); else if (tok.compare("date")==0) insert_date(out); else if (tok.compare("verilog_contents")==0) verilog_contents(out); else if (tok.compare("quartus_contents")==0) quartus_contents(out); else if (tok.compare("verilog")==0) { for (int i=0; i<nfiles; i++) verilog_print(out,verilog_file[i]); } else if (tok.compare("quartus")==0) { for (int i=0; i<nqfiles; i++) quartus_print(out,quartus_file[i]); } else cout << "insert: " << tok << endl; } void qdoc::quartus_contents(FILE *out) { for (int i=0; i<nqfiles; i++) { fputs("<a href=\"#",out); fputs(quartus_file[i].c_str(),out); fputs("\">",out); fputs(quartus_file[i].c_str(),out); fputs("</a><br>\n",out); } } void qdoc::quartus_print(FILE *out, string suffix) { FILE *in; string filename = projname + "." + suffix; errno_t nerr = fopen_s(&in,filename.c_str(),"r"); if (nerr) { cout << "file not found: " << filename << endl; return; } // anchor definition fputs("<a name=\"",out); fputs(suffix.c_str(),out); fputs("\">\n\n",out); // section header fputs("<h3><code>",out); fputs(suffix.c_str(),out); fputs("</code></h3>\n",out); transcribe(in,out); fclose(in); } void transcribe(FILE *in, FILE *out) { char ch; bool done = false; fputs("<p><pre>\n",out); while (!done) { ch = (char) fgetc(in); if (feof(in)) break; if (ch=='<') fputs("<",out); else if (ch=='>') fputs(">",out); else if (ch=='&') fputs("&",out); else if (ch=='\t') fputs(" ",out); else fputc(ch,out); } fputs("</pre>\n",out); fclose(in); } /* set_global_assignment -name FAMILY "Cyclone II" set_global_assignment -name DEVICE EP2C35F672C6 set_global_assignment -name TOP_LEVEL_ENTITY de2lab1 set_global_assignment -name ORIGINAL_QUARTUS_VERSION 6.0 set_global_assignment -name PROJECT_CREATION_TIME_DATE "15:49:53 JANUARY 16, 2007" set_global_assignment -name LAST_QUARTUS_VERSION 6.0 set_global_assignment -name VERILOG_FILE hex_7seg.v */
Maintained by John Loomis, updated Thu Jan 18 11:04:13 2007