/* translation of file "error.k" */
/* generated by:
 *  @(#)$Author$
 */
#ifndef KC_FUNCTIONS_error_HEADER
#define KC_FUNCTIONS_error_HEADER
#include "k.h"    /* in case a user forgets */

namespace kc { }
using namespace kc;
/* included stuff */
//
// The Termprocessor Kimwitu++
//
// Copyright (C) 1991 University of Twente, Dept TIOS.
// Copyright (C) 1998-2003 Humboldt-University of Berlin, Institute of Informatics
// All rights reserved.
//
// Kimwitu++ is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Kimwitu++ is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kimwitu++; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "unpk.h" /* for the definition of uview and printer_functor_class */
extern bool gp_no_fatal_problems;
#include <cctype>
#include <string>
using std::string;

// Cater for broken compilers (eg. MacOS gcc)
#ifndef isalpha
using std::isalpha;
using std::isalnum;
#endif


#include <unistd.h>

namespace kc {

    class view_error_format_class : public view_error_format_baseclass {
	public:
	view_error_format_class(const std::string& fmt): msg(fmt) { }

	void program(const char* p) { replace("%p",p); }
	void file(const char* f) { replace("%f",f); }
	void line(INTEGER l) {
	    char buf[30];
	    sprintf(buf,"%d",l);
	    replace("%l",buf);
	}
	void column(INTEGER c) {
	    char buf[30];
	    sprintf(buf,"%d",c);
	    replace("%c",buf);
	}
	void severity(const char* s) { replace("%s",s); }

	const char* get_msg() {
	    // discard unused patterns
	    program("");
	    file("");
	    replace("%l","");
	    replace("%c","");
	    char* buf;
	    replace("%d",buf=getcwd(NULL,0)); // current directory
	    free(buf);
	    severity("");
	    return msg.c_str();
	}

	void replace(const char* s1, const char* s2) {
	    std::string::size_type pos;
	    while((pos=msg.find(s1)) != std::string::npos) {
		msg.replace(pos,strlen(s1),s2);
	    }
	}
	private:
	std::string msg;
    };

}


class kc_filePrinter : public printer_functor_class {
    public:
    kc_filePrinter(FILE *f=0);
    virtual void operator()(const char* s, uview v);
    int fclose()
    {
	int temp=0;
	if (file)
	    temp=::fclose(file);
	file=0;
	return temp;
    }
    void init(const char *name, const char *mode, const string &type);
    bool check_keyword(const char*);
    FILE *destination() { return file; }
    private:
    FILE *file;
    int lineno;
    string filename;
    int no_of_printed_string_chars; /* to split long double-quoted strings */
    bool doit;
    char lastChar;
    int indent;
    int bs_cnt;
    bool inString;
    bool inChar;
    bool inComment;
    bool inCppComment;
    bool spacePending;
    bool beginOfLine;
    const char* keyword;
    bool indentKeyword;
    bool inPreProStmt;
    static int indent_level;
};

extern kc_filePrinter v_stdout_printer;
extern kc_filePrinter v_hfile_printer;
extern kc_filePrinter v_ccfile_printer;
extern printer_functor_class v_null_printer;


/* end included stuff */


namespace kc {
problem Problem1S (const char *s1);
problem Problem1S1we (const char *s1, withexpression we);
problem Problem1S1ID (const char *s1, ID id);
problem Problem1S1tID (const char *s1, ID id);
problem Problem1S1ID1S1ID (const char *s1, ID id1, const char *s2, ID id2);
problem Problem1S1t1S1ID (const char *s1, IDtype id1, const char *s2, ID id2);
problem Problem1S1INT (const char *s1, INT i1);
problem Problem1S1int1S (const char *s1, int i1, const char *s2);
problem Problem1S1INT1S1ID (const char *s1, INT i1, const char *s2, ID id2);
problem Problem1S1ID1S1ID1S1ID (const char *s1, ID id1, const char *s2, ID id2, const char *s3, ID id3);
problem Problem1S1INT1S1ID1S1ID (const char *s1, INT i1, const char *s2, ID id2, const char *s3, ID id3);
problem Problem1S1storageoption1S1ID (const char *s1, storageoption so, const char *s2, ID id);
problem Problem2S (const char *s1, const char *s2);
problem ProblemSC (const char *s1, casestring s2);
problem Problem3S (const char *s1, const char *s2, const char *s3);
problem Problem4S (const char *s1, const char *s2, const char *s3, const char *s4);
problem Problem3S1int1S (const char *s1, const char *s2, const char *s3, int i1, const char *s4);
void v_report (error e);

} // namespace kc

#endif // !  KC_FUNCTIONS_error_HEADER

