diff options
| -rw-r--r-- | server/src/Makefile.am | 2 | ||||
| -rw-r--r-- | server/src/macroparser.cc | 38 | ||||
| -rw-r--r-- | server/src/macroparser.h | 8 | ||||
| -rw-r--r-- | server/src/macrotool.cc | 9 | ||||
| -rw-r--r-- | server/src/macrotool_fieldnames.cc | 30 | ||||
| -rw-r--r-- | server/src/macrotool_filehandler.cc | 218 | ||||
| -rw-r--r-- | server/src/macrotool_filehandler.h | 36 | ||||
| -rw-r--r-- | server/src/pracrodaopgsql.cc | 27 | 
8 files changed, 348 insertions, 20 deletions
| diff --git a/server/src/Makefile.am b/server/src/Makefile.am index f8f6e21..0589630 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -48,6 +48,7 @@ macrotool_SOURCES = \  	macroparser.cc \  	macrotool_dump.cc \  	macrotool_fieldnames.cc \ +	macrotool_filehandler.cc \  	macrotool_util.cc \  	pracrodao.cc \  	pracrodaopgsql.cc \ @@ -73,6 +74,7 @@ EXTRA_DIST = \  	macroparser.h \  	macrotool_dump.h \  	macrotool_fieldnames.h \ +	macrotool_filehandler.h \  	macrotool_util.h \  	pracrodao.h \  	pracrodaopgsql.h \ diff --git a/server/src/macroparser.cc b/server/src/macroparser.cc index c5b524d..0f7ed76 100644 --- a/server/src/macroparser.cc +++ b/server/src/macroparser.cc @@ -28,6 +28,8 @@  #include "macroparser.h"  #include "configuration.h" +#include <stdio.h> +  // For assert  #include <assert.h> @@ -56,24 +58,37 @@ void MacroParser::error(const char* fmt, ...)    PRACRO_ERR_LOG(macro, "Error in MacroParser: "); -  va_list argp; -  va_start(argp, fmt); -  PRACRO_ERR_LOG_VA(macro, fmt, argp); -  va_end(argp); +  { +    va_list argp; +    va_start(argp, fmt); +    PRACRO_ERR_LOG_VA(macro, fmt, argp); +    va_end(argp); + +    fprintf(stderr, "\n"); +  } -  fprintf(stderr, "\n"); +  { +    char *p; +    va_list argp; +    va_start(argp, fmt); +    if(vasprintf(&p, fmt, argp) != -1) { +      throw Exception("Error in MacroParser: " + std::string(p)); +      free(p); +    } +    va_end(argp); +  } -  throw Exception("Error in MacroParser");  } -MacroParser::MacroParser(std::string macro) +MacroParser::MacroParser(std::string macro, bool abspath)  {    state = UNDEFINED;    m = NULL;    current_map = NULL;    current_script = NULL; -  file = Conf::xml_basedir + "/macros/" + macro + ".xml"; +  if(!abspath) file = Conf::xml_basedir + "/macros/" + macro + ".xml"; +  else file = macro;    PRACRO_DEBUG(macro, "Using macro file: %s\n", file.c_str()); @@ -298,6 +313,13 @@ void MacroParser::parseError(char *buf, size_t len, std::string error, int linen    PRACRO_ERR_LOG(macro, "\tBuffer %u bytes: [", len);    if(fwrite(buf, len, 1, stderr) != len) {}    PRACRO_ERR_LOG(macro, "]\n"); + +  char *slineno; +  if(asprintf(&slineno, " at line %d\n", lineno) != -1) { +    throw Exception(error + slineno); +    free(slineno); +  } +  }  Macro *MacroParser::getMacro() diff --git a/server/src/macroparser.h b/server/src/macroparser.h index 843cb55..3867ca1 100644 --- a/server/src/macroparser.h +++ b/server/src/macroparser.h @@ -45,7 +45,7 @@ class MacroParser : public SAXParser {    } ParserState;  public: -  MacroParser(std::string course); +  MacroParser(std::string macro, bool abspath = false);    ~MacroParser();    void characterData(std::string &data); @@ -53,6 +53,12 @@ public:    void endTag(std::string name);    void parseError(char *buf, size_t len, std::string error, int lineno); +  /** +   * Get a pointer to the parsed macro. +   * NOTE: The allocated memory for the macro is owned by the parser, and will be +   * freed upon parser deletion. +   * @return A pointer to the macro or NULL on error. +   */    Macro *getMacro();  protected: diff --git a/server/src/macrotool.cc b/server/src/macrotool.cc index 44beeef..11c634e 100644 --- a/server/src/macrotool.cc +++ b/server/src/macrotool.cc @@ -41,6 +41,7 @@  #include "macrotool_dump.h"  #include "macrotool_fieldnames.h" +#include "macrotool_filehandler.h"  static const char version_str[] =  "Pracro server v" VERSION "\n" @@ -65,9 +66,10 @@ static const char usage_str[] =  "  -D, --debug ddd     Enable debug messages on 'ddd'; see documentation for details\n"  "\n"  "Commands:\n" -"  dump entity         Dumps 'entity' to screen ('dump help' to see list of entities).\n" -"  fieldnames entity   Add/delete/update entries in the fieldnames database\n" -"                      ('fieldnames help' to see list of entities).\n" +"  dump entity          Dumps 'entity' to screen ('dump help' to see list of entities).\n" +"  fieldnames entity    Add/delete/update entries in the fieldnames database\n" +"                       ('fieldnames help' to see list of entities).\n" +"  filehandler entity  Handle macro files ('macrohandler help' to see list of entities).\n"  ;  ConfigurationParser *configparser = NULL; @@ -152,6 +154,7 @@ int main(int argc, char *argv[])    if(command == "dump") macrotool_dump(params);    if(command == "fieldnames") macrotool_fieldnames(params); +  if(command == "filehandler") macrotool_filehandler(params);    // Clean up    if(configfile) free(configfile); diff --git a/server/src/macrotool_fieldnames.cc b/server/src/macrotool_fieldnames.cc index eeed648..3c3f8b7 100644 --- a/server/src/macrotool_fieldnames.cc +++ b/server/src/macrotool_fieldnames.cc @@ -37,17 +37,21 @@  static const char usage_str[] =  "  help            Prints this helptext.\n" -"  set name desc   Add a field (or update) called 'name', described as 'desc'\n" +"  add name desc   Add a field called 'name', described as 'desc'\n" +"  del name        Delete a field called 'name'\n" +"  list            List all fieldnames as well as their macro references.\n"  ;  static void add(std::string name, std::string desc)  { -#ifndef WITHOUT_DB -  PRACRO_DEBUG("SET (name: %s - desc: %s)\n", name.c_str(), desc.c_str()); -#else /*WITHOUT_DB*/ -  printf("Project not compiled with db spport.") -#endif/*WITHOUT_DB*/ +  Database db("pgsql", Conf::database_addr, "", Conf::database_user, Conf::database_passwd, ""); +  db.addFieldname(name, desc); +} +static void del(std::string name) +{ +  Database db("pgsql", Conf::database_addr, "", Conf::database_user, Conf::database_passwd, ""); +  db.delFieldname(name);  }  static std::vector<std::string> getWidgetNames(Widget &w) @@ -170,9 +174,9 @@ void macrotool_fieldnames(std::vector<std::string> params)      return;    } -  if(params[0] == "set") { +  if(params[0] == "add") {      if(params.size() != 3) { -      printf("The command 'set' needs 2 parameters.\n"); +      printf("The command 'add' needs 2 parameters.\n");        printf(usage_str);        return;      } @@ -180,6 +184,16 @@ void macrotool_fieldnames(std::vector<std::string> params)      return;    } +  if(params[0] == "del") { +    if(params.size() != 2) { +      printf("The command 'del' needs 1 parameter.\n"); +      printf(usage_str); +      return; +    } +    del(params[1]); +    return; +  } +    if(params[0] == "help") {      printf(usage_str);      return; diff --git a/server/src/macrotool_filehandler.cc b/server/src/macrotool_filehandler.cc new file mode 100644 index 0000000..524761c --- /dev/null +++ b/server/src/macrotool_filehandler.cc @@ -0,0 +1,218 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + *            macrotool_filehandler.cc + * + *  Fri Jul 17 08:48:09 CEST 2009 + *  Copyright 2009 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of Pracro. + * + *  Pracro 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. + * + *  Pracro 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 Pracro; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "macrotool_filehandler.h" + +#include <fstream> +#include <ios> + +#include "macroparser.h" +#include "template.h" + +#include "debug.h" + +#include "macrotool_util.h" + +#include "configuration.h" + +static const char usage_str[] = +"  help           Prints this helptext.\n" +"  add file       Add a file called 'file' to the macro or template folder, according\n" +"                  to its contents.\n" +"  check file     Check if a file is valid, and print a resume of its contents.\n" +; + +/** +class Macro { +public: +  std::vector< Query > queries; +  std::vector< Map > maps; +  std::vector< Script > scripts; +  Widget window; +  std::map< std::string, std::string > attributes; +  Resume resume; +}; + **/ +static bool check(std::string file, std::string *name = NULL, std::string *version = NULL); +static bool check(std::string file, std::string *name, std::string *version) +{ +  try { +    MacroParser parser(file, true); +    parser.parse(); +    Macro *macro = parser.getMacro(); +    if(!macro) { +      printf("Macro malformed!\n"); +      return false; +    } + +    printf("Parsing of %s was succesful.\n", file.c_str()); +    printf("Name:    %s\n", macro->attributes["name"].c_str()); +    printf("Version: %s\n", macro->attributes["version"].c_str()); + +    if(name) *name = macro->attributes["name"]; +    if(version) *version = macro->attributes["version"]; + +  } catch( std::exception &e ) { +    printf("%s\n", e.what()); +    return false; +  } +  return true; +} + +static bool macro_exists(std::string name, std::string version, std::string &clashfile) +{ +  std::vector<std::string> macrofiles = getMacros(); +  std::vector<std::string>::iterator mfs = macrofiles.begin(); +  while(mfs != macrofiles.end()) { +    std::string macroname = mfs->substr(0, mfs->length() - 4); + +    MacroParser parser(macroname); +    parser.parse(); +    Macro *macro = parser.getMacro(); + +    if(name == macro->attributes["name"] && +       version == macro->attributes["version"]) { +      clashfile = *mfs; +      return true; +    } + +    mfs++; +  } + +  return false; +} + +static std::string strippath(std::string filename) +{ +  if(filename.find('/') == std::string::npos) return filename; +  return filename.substr(filename.rfind('/')+1); +} + +static bool file_exist(std::string file) +{ +  FILE *fp =  fopen(file.c_str(), "r"); +  if(!fp) return false; +  fclose(fp); +  return true; +} + +static void add(std::string file) +{ +  std::string name; +  std::string version; +  std::string clashfile; +  std::string target; + +  if(!check(file, &name, &version)) { +    printf("File not a valid macro file.\nAborting...\n"); +    return; +  } + +  if(macro_exists(name, version, clashfile)) { +    printf("WARNING: A macro with that name and version already exists." +           " THE EXISTING FILE WILL BE OVERWRITTEN!\n"); +    printf("File: %s\n", clashfile.c_str()); +    char answer[32]; +    answer[0] = '\0'; +    while(std::string(answer) != "yes\n" && std::string(answer) != "no\n") { +      if(answer[0] == '\0') printf("Are you sure you want to put the file in the macro directory? [yes/no]\n"); +      else printf("Please answer 'yes' or 'no'\n"); +      fgets(answer, sizeof(answer), stdin); +    } +     +    if(std::string(answer) == "no\n") { +      printf("Aborting...\n"); +      return; +    } +    target = Conf::xml_basedir + "/macros/" + clashfile; +  } else { +    target = Conf::xml_basedir + "/macros/" + strippath(file); + +    size_t cnt = 0; +    while(file_exist(target)) { +      char *num; +      if(cnt) asprintf(&num, "-%d", cnt); +      else num = strdup(""); +      target = Conf::xml_basedir + "/macros/" + name + "-" + version + num + ".xml"; +      printf("Trying: %d %s\n", cnt, target.c_str()); +      free(num); +      cnt++; +    } +  } + +  printf("Copying '%s' to '%s' ...\n", file.c_str(), target.c_str()); + +  { +    std::ifstream ifs(file.c_str(), std::ios::binary); +    if(!ifs) { +      printf("Could read source file.\nAborting...\n"); +      return; +    } +    std::ofstream ofs(target.c_str(), std::ios::binary); +    ofs << ifs.rdbuf(); +  } +  printf("done\n"); +} + +void macrotool_filehandler(std::vector<std::string> params) +{ +  if(params.size() < 1) { +    printf(usage_str); +    return; +  } + +  PRACRO_DEBUG(filehandler, "filehandler: %s\n", params[0].c_str()); + +  if(params[0] == "add") { +    if(params.size() != 2) { +      printf("The command 'add' needs 1 parameter.\n"); +      printf(usage_str); +      return; +    } +    add(params[1]); +    return; +  } + +  if(params[0] == "check") { +    if(params.size() != 2) { +      printf("The command 'check' needs 1 parameter.\n"); +      printf(usage_str); +      return; +    } +    check(params[1]); +    return; +  } + +  if(params[0] == "help") { +    printf(usage_str); +    return; +  } + +  printf("Unknown command '%s'\n", params[0].c_str()); +  printf(usage_str); +  return; +} diff --git a/server/src/macrotool_filehandler.h b/server/src/macrotool_filehandler.h new file mode 100644 index 0000000..70777fc --- /dev/null +++ b/server/src/macrotool_filehandler.h @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + *            macrotool_filehandler.h + * + *  Fri Jul 17 08:48:09 CEST 2009 + *  Copyright 2009 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of Pracro. + * + *  Pracro 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. + * + *  Pracro 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 Pracro; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#ifndef __PRACRO_MACROTOOL_FILEHANDLER_H__ +#define __PRACRO_MACROTOOL_FILEHANDLER_H__ + +#include <vector> +#include <string> + +void macrotool_filehandler(std::vector<std::string> params); + +#endif/*__PRACRO_MACROTOOL_FILEHANDLER_H__*/ diff --git a/server/src/pracrodaopgsql.cc b/server/src/pracrodaopgsql.cc index 683fe85..7159b03 100644 --- a/server/src/pracrodaopgsql.cc +++ b/server/src/pracrodaopgsql.cc @@ -244,10 +244,37 @@ unsigned PracroDAOPgsql::nrOfCommits(std::string patientid, std::string macronam  void PracroDAOPgsql::addFieldname(std::string name, std::string description)  { +  std::stringstream timestamp; timestamp << time(NULL); +  std::string ts; +  try { +    pqxx::work W(*conn); +    ts = "INSERT INTO fieldnames (name, description, \"timestamp\") VALUES (" +      " '" + W.esc(name) + "', " +      " '" + W.esc(description) + "', " +      " '" + W.esc(timestamp.str()) + "' " +      ")" +      ; +    PRACRO_DEBUG(sql, "Query: %s\n", ts.c_str()); +    pqxx::result R = W.exec(ts); +    W.commit(); +  } catch (std::exception &e) { +    PRACRO_ERR_LOG(db, "Query failed: %s: %s\n", e.what(), ts.c_str()); +  }  }  void PracroDAOPgsql::delFieldname(std::string name)  { +  std::string ts; +  try { +    pqxx::work W(*conn); +    ts = "DELETE FROM fieldnames WHERE name=" +      "'" + W.esc(name) + "' "; +    PRACRO_DEBUG(sql, "Query: %s\n", ts.c_str()); +    pqxx::result R = W.exec(ts); +    W.commit(); +  } catch (std::exception &e) { +    PRACRO_ERR_LOG(db, "Query failed: %s: %s\n", e.what(), ts.c_str()); +  }  }  std::vector<Fieldname> PracroDAOPgsql::getFieldnames() | 
