/* Label.C * * Stores user-defined labels for backwards and forwards referencing with * the \ref and \pageref commands. * * Copyright 1992 Jonathan Monsarrat. Permission given to freely distribute, * edit and use as long as this copyright statement remains intact. * */ #include #include #include #include #include "Global.h" #include "Counter.h" #include "Operator.h" Label::Label(char *name, int chapter, int section) { _name = strdup(name); _chapter = chapter; _section = section; _referenced = 0; } Label::~Label() { delete _name; } Label::match(char *name) { return !strcmp(name, _name); } Labels::Labels() { numlabels = 0; unknown_references = 0; } Labels::~Labels() { for(int x=0; x < numlabels; x++) delete label[x]; } void Labels::add_label(char *labelname) { if(numlabels > MAXLABELS - 2) Global::files->fatal_error("Too many labels defined"); for(int x=0; x < numlabels; x++) if(label[x]->match(labelname)) { char message[50]; sprintf(message, "Same label name %s defined twice", labelname); Global::files->fatal_error(message); } label[numlabels++] = new Label(labelname, (int)Stack::get(Environment::PCounter, Counter::Chapter, ""), (int)Stack::get(Environment::PCounter, Counter::Section, "")); } /* Print a reference to a given labelname done from the \ref command. * Must handle forward referencing as a special case. */ void Labels::print_ref(char *labelname) { for(int x=0; x < numlabels; x++) if(label[x]->match(labelname)) { char printout[MAXSTRING]; sprintf(printout,"%d.%d",label[x]->_chapter,label[x]->_section); Operator::plaintext(printout); label[x]->_referenced = 1; return; } /* Label is undefined. We assume it is a forward referencing problem */ unknown_references = 1; Global::files->outfile << endl << "LAMETEXLABELREF" << labelname << endl; } /* Shutdown the program by going through the file and changing all the * undone label references to the correct information. */ void Labels::shutdown() { ifstream outfile; ofstream tempfile; char buffer[MAXSTRING]; char *p; char *labelname; if(!unknown_references) return; cerr << "Handling forward references..." << endl; outfile.open(Global::files->outfilename); tempfile.open("lametex.temp"); outfile.getline(buffer, MAXSTRING, '\n'); while(!outfile.eof() && !outfile.fail()) { if((p = strstr(buffer, "LAMETEXLABELREF"))!=NULL) { labelname = (char *)(p + 15); for(int x=0; x < numlabels; x++) if(label[x]->match(labelname)) { tempfile << "(" << label[x]->_chapter << "." << label[x]->_section << ") NW" << endl; label[x]->_referenced = 1; break; } if(x >= numlabels) { cerr << "No match found for label " << labelname << endl; exit(-1); } } else { tempfile << buffer << endl; } outfile.getline(buffer, MAXSTRING, '\n'); } outfile.close(); tempfile.close(); sprintf(buffer, "mv lametex.temp %s", Global::files->outfilename); system(buffer); }