Back Midas Rome Roody Rootana
  Rome Analyzer Framework, Page 6 of 11  Not logged in ELOG logo
ID Date Author Topic Subject
  111   13 Jan 2006 Ryu SawadaSuggestionConfiguration file
done.
Program searches configuration XML file in ./ and ./config
  110   09 Jan 2006 Ryu SawadaSuggestionQuit mode
Sometimes I hear that going to interactive session after end of analysis is uncomfortable. In fact it is possible to quit program immediately with -b option.
But -b is not only for that, It suppresses print. So I propose to make QuidMode in which program exit without going interactive session.
-q option is good, because ROOT has same option which means quit program just after macro is executed.
  109   09 Jan 2006 Ryu SawadaSuggestionConfiguration file
About configuration XML files.

Now we merged ROME and ARGUS.
So I expect that users often have several configuration files for one project.

But I realized many people don't know that they can specify configuration file.

So I propose following scheme.

* When a program starts, it searches all XML files located in current directory which has <Configuration> tag at the top.
* If it does not find any XML file, it asks user to generate new one.
   * ask configuration type [R/A/M/N]
   * ask filename. Default is romeConfig.xml
* If it find only one XML file, it reads the XML file.
* If it find several XML files, it asks user which file should be used with a prompt like,
     Which configuration file do you use ?
      [1] filename1.xml
      [2] romeConfig.xml
      [3] filename2.xml
      [q] quit program
* When user starts program with option -c, it asks creates new configuration anyway.
* When user starts program with option -i, it uses specified file.
  108   06 Jan 2006 Ryu SawadaForumTNetFolder.h
You can download the latest TNetFolder.h from the repository with web browser.

http://savannah.psi.ch/websvn/listing.php?repname=rome&path=%2Ftrunk%2Frome%2F&rev=0&sc=0


TNetFolder.h was added to "rome/include" in two weeks ago. Please make sure you have recent version.
If your copy is old, please update your copy with "svn update" command.


If the problem is not still fixed, could you paste error message from compiler ?
  107   06 Jan 2006 Steven SheetsForumTNetFolder.h
I just downloaded ROME v 2.0, I think. After running the make file I try and use romebuilder.exe
on the example stepbystep given in the download. When running romebuilder.exe
on stepbystep.xml I found it could not locate the file TNetFolder.h.

I googled this file and found a version of it which I copied to rome/include but still the builder will not build the analyzer. At this point I'm not sure how to get around this problem. If you have suggestions I'd appreciate it.

thanks,
Steven Sheets
  106   18 Dec 2005 Ryu SawadaInfoRe-organization of directory structure
I and Matthias discussed about directory structure. In previous structure, files which can be overwritten and others were placed in the same directory.

We thought it would be better to separate two kinds of files clearly. So I modified directory structure like following.
|-- include
|   |-- daqs       : include files of user defined DAQs.
|   |-- databases  : include files of user defined databases.
|   |-- folders    : include files of folders come when 'ChangeableClassFile" is true.
|   |-- generated  : include files which can be overwritten by builder.
|   `-- tasks      : include files of tasks come when 'ChangeableClassFile" is true.
`-- src
    |-- daqs       : source files of user defined DAQs.
    |-- databases  : source files of user defined databases.
    |-- folders    : source files of folders come when 'ChangeableClassFile" is true.
    |-- generated  : source files which can be overwritten by builder.
    `-- tasks      : source files of tasks.         

All ROME user need to modify the place of files and also #include statement.
  105   07 Dec 2005 Ryu SawadaSuggestionProposal reorganiztion directory structure
*) Currently, builder makes many files in the top directory.

XXXFolderDict.cpp
XXXFrameworkDict.cpp
XXXROMEDict.cpp
XXXTaskDict.cpp
XXXUserDict.cpp
XXXFolderDict.h
XXXFrameworkDict.h
XXXROMEDict.h
XXXTaskDict.h
XXXUserDict.h
xxxproject.exe
XXXProject.html
XXXUserHTML.html
libXXXProject.so
(romeConfig.xml)
Makefile
Makefile.usr

But I think it makes hard to find important files. And I'm afraid people feel ROME difficult.
Really important files are romeConfig.xml, Makefile and xxxproject.exe. So I propose followings
1) make "dict" directory and put all dictionary related files in it.
2) I have proposed to make XXXUserHTML.html before. But I started to feel this feature is not necessary any more.
3) remove libXXXProject.so from "all:" in Makefile. Users need to type "make so" to create shared library.
Makefile will look like
.
.
all: obj blank.d xxxproject.exe
.
.
so: libxxxproject.so
libxxxproject.so: $(objects)
g++ $(Flags) $(soflags) -o libxxxproject.so $(objects) $(Libraries)

*) There are still some complains that it is not easy to know which files are overwritten by builder
For instance, there is no warning messages in the header of XXXProject.html and Makefile.
And some files under "framework" directory are persistent. For instance user defined DAQ, user defined
database and folders with "editable class" flag are persistent. So I propose to separate them
at the first level instead of separating "framework" and "task". It will look like

top
|-- framework
`-- user
|-- daqs
|-- databases
|-- folders
`-- tasks

daqs, databases and folders may appear only when necessary.

All files which will be overwritten are put in framework. And others go under user.
When a task does not have "editable class" flag. the .cpp will go to user/tasks/ and
the .h file will go to framework/

This change is more like matter of favor.
And there are disadvantages.
.h will be various places, and it becomes difficult to find a .h file to know the class structure.
And the file with the same name can be in different places.
For instance, normally .h file of folder will be put in framework, but if it has "editable class" flag it will be put in user/folders/.
And if one changes "editable class" flag meanwhile, there can be two files with the same name. It may cause problem

With this change all ROME users need to move their files, so we have to think carefully.

( Anoter possibility is preparing nice document on ROME homepage instead of changing directory structure. )

P.S.
This is a very small point and is not related to directory structure.
Normally people associate online data taking with the word "DAQ". But in ROME, DAQSystem is something like input data format. ROME and database are not clearly DAQ.
When we have chanse, it may be good to rename nicer.
  104   16 Nov 2005 Matthias SchneebeliInfoChanged Root DAQ to Rome DAQ
I have changed the name of ROMEs input/output DAQ system from Root to Rome.
This has to implications for the user :

1. One has to select 'rome' intead of 'root' for the <DAQSystem> tag in the romeConfig file.

2. To access this DAQ system one has to call GetRome() instead of GetRoot()

Matthias
  103   17 Oct 2005 Matthias SchneebeliInfoMoved ROME from cvs to subversion
ROME moved from the cvs repository to a subversion repository.

Subversion repositories are much easier to maintain.

For the user almost nothing changes.
'cvs checkout' translates to 'svn checkout' and so on.

Subversion can be downloaded from http://subversion.tigris.org/project_packages.html

I hope this will not cause much inconvenience.

Matthias
  102   14 Oct 2005 Ryu SawadaInfoEventID
It seems that when tasks have different eventID from 'a', event methods are not executed.

I modified ROMETask.cpp for temporary solution like
else if ( strncmp(gROME->GetNameOfActiveDAQ(),"midas",5) ||
( !strncmp(&fEventID,"a",1) || !strncmp(option,&fEventID,1) )
) {
fCurrentEventMethod = "Event";
TimeStart();
if (gROME->isFillEvent())
Event();
TimeEnd();
}
By this change, eventID does not have meaning for DAQSystems other than midas.

If eventID should have meaning also in root mode, please impleament something to fill ROMEAnalyzer::fEventID in this mode.
  101   07 Oct 2005 Ryu SawadaForumDividing xml the definition xml file.
> I made a patch to enable it with mxml.
> Please test it.
> 
> If it is reliable, I will commit it.
> 
> ----
> cd $ROMESYS
> patch -p0 < mxml.diff  
> ----

I modified bugs, and commited.
Attachment 1: mxml.patch
? mxml.c
? mxml.h
? mxml.patch
? obj
? src/indent.txt
Index: include/mxml.h
===================================================================
RCS file: /usr/local/cvsroot/rome/include/mxml.h,v
retrieving revision 1.7
diff -u -r1.7 mxml.h
--- include/mxml.h	12 Jul 2005 09:04:15 -0000	1.7
+++ include/mxml.h	7 Oct 2005 13:15:53 -0000
@@ -43,6 +43,11 @@
 #define PROCESSING_INSTRUCTION_NODE   3
 #define COMMENT_NODE                  4
 #define DOCUMENT_NODE                 5
+#define ENTITY_NODE                   6
+
+#define INTERNAL_ENTITY               0
+#define EXTERNAL_ENTITY               1
+#define MXML_MAX_ENTITY            1000
 
 typedef struct {
    int  fh;
@@ -115,6 +120,7 @@
 PMXML_NODE mxml_create_root_node();
 PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size);
 PMXML_NODE mxml_parse_buffer(char *buffer, char *error, int error_size);
+PMXML_NODE mxml_parse_entity(char **buf, char *error, int error_size);
 int mxml_write_tree(char *file_name, PMXML_NODE tree);
 void mxml_debug_tree(PMXML_NODE tree, int level);
 void mxml_free_tree(PMXML_NODE tree);
Index: src/mxml.c
===================================================================
RCS file: /usr/local/cvsroot/rome/src/mxml.c,v
retrieving revision 1.8
diff -u -r1.8 mxml.c
--- src/mxml.c	11 May 2005 12:50:02 -0000	1.8
+++ src/mxml.c	7 Oct 2005 13:15:53 -0000
@@ -1209,6 +1209,30 @@
 
             p += 2;
 
+         } else if (strncmp(p, "!ENTITY", 7) == 0) {
+
+            /* found !ENTITY element */
+            pnew = mxml_add_special_node(ptree, ENTITY_NODE, "ENTYTY", NULL);
+            pv = p + 1;
+
+            p++;
+            if (strstr(p, ">") == NULL)
+               return read_error(HERE, "Unterminated !ENTITY element");
+
+            while (*p != '>') {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+
+            len = (size_t)p - (size_t)pv;
+            pnew->value = (char *)malloc(len+1);
+            memcpy(pnew->value, pv, len);
+            pnew->value[len] = 0;
+            mxml_decode(pnew->value);
+
+            p ++;
+
          } else {
             
             /* found normal element */
@@ -1407,6 +1431,422 @@
 
 /*------------------------------------------------------------------*/
 
+PMXML_NODE mxml_parse_entity(char **buf, char *error, int error_size)
+/* parse !ENTYTY entries of XML files and replace with references. Return NULL
+   in case of error, return error description. Optional file_name is used
+   for error reporting if called from mxml_parse_file() */
+{
+   char *p;
+   char *pv;
+   char delimiter;
+   int i, j, k, line_number;
+   char *replacement;
+   char entity_name[MXML_MAX_ENTITY][256];
+   char entity_reference_name[MXML_MAX_ENTITY][256];
+   char *entity_value[MXML_MAX_ENTITY];
+   int entity_type[MXML_MAX_ENTITY];    /* internal or external */
+   int nentity;
+   int fh, length, len;
+   char *buffer;
+   PMXML_NODE root = mxml_create_root_node();   /* dummy for 'HERE' */
+   char *file_name = NULL;      /* dummy for 'HERE' */
+   int ip;                      /* counter for entity value */
+
+   for (ip = 0; ip < MXML_MAX_ENTITY; ip++)
+      entity_value[ip] = NULL;
+
+   line_number = 1;
+   nentity = -1;
+
+   /* copy string to temporary space */
+   buffer = (char *) malloc(strlen(*buf) + 1);
+   if (buffer == NULL) {
+      return read_error(HERE, "Cannot allocate memory.");
+   }
+
+   p = buffer;
+
+   strcpy(buffer, *buf);
+   free(*buf);
+
+   /* search !ENTITY */
+   do {
+      if (*p == '<') {
+
+         /* found new entity */
+         p++;
+         while (*p && isspace(*p)) {
+            if (*p == '\n')
+               line_number++;
+            p++;
+         }
+         if (!*p) {
+/*
+            free(buffer);
+            for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+               free(entity_value[ip]);
+*/
+            return read_error(HERE, "Unexpected end of file");
+         }
+
+         if (strncmp(p, "!ENTITY", 7) == 0) {
+
+            /* found entity */
+            nentity++;
+            if (nentity >= MXML_MAX_ENTITY) {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Too much entities");
+            }
+
+            pv = p + 7;
+            while (*pv == ' ')
+               pv++;
+
+            /* extract entity name */
+            p = pv;
+
+            while (*p && isspace(*p) && *p != '<' && *p != '>') {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+            if (!*p) {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected end of file");
+            }
+            if (*p == '<' || *p == '>') {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected \'%c\' inside !ENTITY", *p);
+            }
+
+            pv = p;
+            while (*pv && !isspace(*pv) && *pv != '<' && *pv != '>')
+               pv++;
+
+            if (!*pv) {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected end of file");
+            }
+            if (*pv == '<' || *pv == '>') {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv,
+                                 &entity_name[nentity][1]);
+            }
+
+            len = (size_t) pv - (size_t) p;
+
+            entity_name[nentity][0] = '&';
+            i = 1;
+            entity_name[nentity][i] = 0;
+            while (*p && !isspace(*p) && *p != '/' && *p != '>' && *p != '<' && i < 253)
+               entity_name[nentity][i++] = *p++;
+            entity_name[nentity][i++] = ';';
+            entity_name[nentity][i] = 0;
+
+            if (!*p) {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected end of file");
+            }
+            if (*p == '<') {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected \'<\' inside entity \"%s\"", &entity_name[nentity][1]);
+            }
+
+            /* extract replacement or SYSTEM */
+            while (*p && isspace(*p)) {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+            if (!*p) {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected end of file");
+            }
+            if (*p == '>') {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
+            }
+
+            /* check if SYSTEM */
+            if (strncmp(p, "SYSTEM", 6) == 0) {
+               entity_type[nentity] = EXTERNAL_ENTITY;
+               p += 6;
+            } else {
+               entity_type[nentity] = INTERNAL_ENTITY;
+            }
+
+            /* extract replacement */
+            while (*p && isspace(*p)) {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+            if (!*p) {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected end of file");
+            }
+            if (*p == '>') {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
+            }
+
+            if (*p != '\"' && *p != '\'') {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Replacement was not found for entity \"%s\"",
+                                 &entity_name[nentity][1]);
+            }
+            delimiter = *p;
+            p++;
+            if (!*p) {
+/*
+               free(buffer);
+               for(ip=0;ip<MXML_MAX_ENTITY;ip++)
+                  free(entity_value[ip]);
+*/
+               return read_error(HERE, "Unexpected end of file");
+            }
+            pv = p;
+            while (*pv && *pv != delimiter)
+               pv++;
+
... 207 more lines ...
  100   06 Oct 2005 Ryu SawadaForumDividing xml the definition xml file.
> I am thinking to divide my definition xml file into several files.
> 
> I do not know if there is a general way, but I found some web pages mentioning about it. According to 
> these pages we can include an xml document to  other one like.
> 
> ---------- booklist.xml ------------
> <?xml version="1.0"?>
> <!DOCTYPE books [
> <!ENTITY book1 SYSTEM "book1.xml">
> ]>
> 
> <books>
>   &book1;
> </books>
> ------------------------------------
> ------------ book1.xml -------------
> <?xml version="1.0"?>
> <book>
>   <title>Title of the book</title>
>   <author>Author of the book</author>
> </book>
> ------------------------------------
> 
> Is it possible to do it with mxml ?

I made a patch to enable it with mxml.
Please test it.

If it is reliable, I will commit it.

----
cd $ROMESYS
patch -p0 < mxml.diff  
----
Attachment 1: mxml.diff
Index: include/mxml.h
===================================================================
RCS file: /usr/local/cvsroot/rome/include/mxml.h,v
retrieving revision 1.7
diff -u -r1.7 mxml.h
--- include/mxml.h	12 Jul 2005 09:04:15 -0000	1.7
+++ include/mxml.h	6 Oct 2005 21:53:13 -0000
@@ -43,6 +43,10 @@
 #define PROCESSING_INSTRUCTION_NODE   3
 #define COMMENT_NODE                  4
 #define DOCUMENT_NODE                 5
+#define ENTITY_NODE                   6
+
+#define INTERNAL_ENTITY               0
+#define EXTERNAL_ENTITY               1
 
 typedef struct {
    int  fh;
@@ -115,6 +119,7 @@
 PMXML_NODE mxml_create_root_node();
 PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size);
 PMXML_NODE mxml_parse_buffer(char *buffer, char *error, int error_size);
+PMXML_NODE mxml_parse_entity(char *buf, char *error, int error_size);
 int mxml_write_tree(char *file_name, PMXML_NODE tree);
 void mxml_debug_tree(PMXML_NODE tree, int level);
 void mxml_free_tree(PMXML_NODE tree);
Index: src/mxml.c
===================================================================
RCS file: /usr/local/cvsroot/rome/src/mxml.c,v
retrieving revision 1.8
diff -u -r1.8 mxml.c
--- src/mxml.c	11 May 2005 12:50:02 -0000	1.8
+++ src/mxml.c	6 Oct 2005 21:53:13 -0000
@@ -1209,6 +1209,30 @@
 
             p += 2;
 
+         } else if (strncmp(p, "!ENTITY", 7) == 0) {
+
+            /* found !ENTITY element */
+            pnew = mxml_add_special_node(ptree, ENTITY_NODE, "ENTYTY", NULL);
+            pv = p+1;
+
+            p++;
+            if (strstr(p, ">") == NULL)
+               return read_error(HERE, "Unterminated !ENTITY element");
+
+            while (*p != '>') {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+
+            len = (size_t)p - (size_t)pv;
+            pnew->value = (char *)malloc(len+1);
+            memcpy(pnew->value, pv, len);
+            pnew->value[len] = 0;
+            mxml_decode(pnew->value);
+
+            p ++;
+
          } else {
             
             /* found normal element */
@@ -1407,6 +1431,249 @@
 
 /*------------------------------------------------------------------*/
 
+PMXML_NODE mxml_parse_entity(char *buf, char *error, int error_size)
+/* parse !ENTYTY entries of XML files and replace with references. Return NULL
+   in case of error, return error description. Optional file_name is used
+   for error reporting if called from mxml_parse_file() */
+{
+   char *p;
+   char *pv;
+   char delimiter;
+   int  i,j,k, line_number;
+   char replacement[1000];
+   char entity_name[256][256];
+   char entity_reference_name[256][256];
+   char *entity_value[256];
+   int  entity_type[256]; /* internal or external */
+   int  nentity;
+   int  fh, length,len;
+   char *buffer;
+   PMXML_NODE root = mxml_create_root_node(); // dummy for 'HERE'
+   char *file_name = NULL; // dummy for 'HERE'
+
+   /* copy string to temporary space */
+   buffer = (char *)malloc(strlen(buf)+1);
+   strcpy(buffer,buf);
+   free(buf);
+
+   p = buffer;
+   line_number = 1;
+   nentity = -1;
+
+   /* search !ENTITY */
+   do {
+      if (*p == '<') {
+
+         /* found new entity */
+         p++;
+         while (*p && isspace(*p)) {
+            if (*p == '\n')
+               line_number++;
+            p++;
+         }
+         if (!*p)
+            return read_error(HERE, "Unexpected end of file");
+
+         if (strncmp(p, "!ENTITY", 7) == 0) {
+
+            /* found entity */
+            nentity++;
+            if(nentity>=1000)
+               return read_error(HERE, "Too much entities");
+
+            pv = p+7;
+            while (*pv == ' ')
+               pv++;
+
+            /* extract entity name */
+            p = pv;
+
+            while (*p && isspace(*p) && *p != '<' && *p != '>') {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+            if (!*p)
+               return read_error(HERE, "Unexpected end of file");
+            if (*p == '<' || *p == '>')
+               return read_error(HERE, "Unexpected \'%c\' inside !ENTITY", *p);
+
+            pv = p;
+            while (*pv && !isspace(*pv) && *pv != '<' && *pv != '>')
+               pv++;
+
+            if (!*pv)
+               return read_error(HERE, "Unexpected end of file");
+            if (*pv == '<'  || *pv == '>' )
+               return read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]);
+
+            len = (size_t)pv - (size_t)p;
+            if (len > (int)sizeof(replacement)-1)
+               len = sizeof(replacement)-1;
+            memcpy(replacement, p, len);
+            replacement[len] = 0;
+            mxml_decode(replacement);
+
+            entity_name[nentity][0] = '&';
+            i = 1;
+            entity_name[nentity][i] = 0;
+            while (*p && !isspace(*p) && *p != '/' && *p != '>' && *p != '<' && i<253)
+               entity_name[nentity][i++] = *p++;
+            entity_name[nentity][i++] = ';';
+            entity_name[nentity][i] = 0;
+
+            if (!*p)
+               return read_error(HERE, "Unexpected end of file");
+            if (*p == '<')
+               return read_error(HERE, "Unexpected \'<\' inside entity \"%s\"", &entity_name[nentity][1]);
+
+            /* extract replacement or SYSTEM*/
+            while (*p && isspace(*p)) {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+            if (!*p)
+               return read_error(HERE, "Unexpected end of file");
+            if (*p == '>')
+               return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
+
+            /* check if SYSTEM */
+            if(strncmp(p, "SYSTEM", 6) == 0){
+               entity_type[nentity] = EXTERNAL_ENTITY;
+               p += 6;
+            }
+            else{
+               entity_type[nentity] = INTERNAL_ENTITY;
+            }
+
+            /* extract replacement */
+            while (*p && isspace(*p)) {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+            if (!*p)
+               return read_error(HERE, "Unexpected end of file");
+            if (*p == '>')
+               return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]);
+
+            if (*p != '\"' && *p != '\'')
+               return read_error(HERE, "Replacement was not found for entity \"%s\"", &entity_name[nentity][1]);
+            delimiter = *p;
+            p++;
+            if (!*p)
+               return read_error(HERE, "Unexpected end of file");
+            pv = p;
+            while (*pv && *pv != delimiter )
+               pv++;
+
+            if (!*pv)
+               return read_error(HERE, "Unexpected end of file");
+            if (*pv == '<' )
+               return read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]);
+
+            len = (size_t)pv - (size_t)p;
+            if (len > (int)sizeof(replacement)-1)
+               len = sizeof(replacement)-1;
+            memcpy(replacement, p, len);
+            replacement[len] = 0;
+
+            if(entity_type[nentity] == EXTERNAL_ENTITY){
+               strcpy(entity_reference_name[nentity],replacement);
+            }
+            else{
+               entity_value[nentity] = (char *)malloc(strlen(replacement));
+               strcpy(entity_value[nentity],replacement);
+            }
+
+            p = pv;
+            while (*p && isspace(*p)) {
+               if (*p == '\n')
+                  line_number++;
+               p++;
+            }
+            if (!*p)
+               return read_error(HERE, "Unexpected end of file");
+         }
+      }
+
+      /* go to next element */
+      while (*p && *p != '<') {
+         if (*p == '\n')
+            line_number++;
+         p++;
+      }
+   } while (*p);
+   nentity++;
+
+   /* read external file */
+   for(i=0;i<nentity;i++){
+      if(entity_type[i] == EXTERNAL_ENTITY){
+         fh = open(entity_reference_name[i], O_RDONLY | O_TEXT, 0644);
+
+         if (fh == -1) {
+            return read_error(HERE, "Unable to open file \"%s\"",entity_reference_name[i]);
+         }
+
+         length = lseek(fh, 0, SEEK_END);
+         lseek(fh, 0, SEEK_SET);
+         entity_value[i] = (char *)malloc(length+1);
+         if (entity_value[i] == NULL) {
+            close(fh);
+            return read_error(HERE, "Cannot allocate buffer of %d bytes for \"%s\".",length+1,&entity_name[1]);
+         }
+
+         /* read complete file at once */
+         length = read(fh, entity_value[i], length);
+         entity_value[i][length] = 0;
+         close(fh);
+      }
+   }
+
+   /* count length of output string */
+   length = strlen(buffer);
+   for(i=0;i<nentity;i++){
+      p = buffer;
+      while(1){
+         pv =strstr(entity_name[i],p);
+         if(pv){
+            length += -strlen(entity_name[i]) + strlen(entity_value[i]);
+            p = pv+1;
+         }
+         else{
+            break;
+         }
+      }
+   }
+
+   /* allocate memory */
+   buf = (char *)malloc(length+1);
+
+   /* replace entities */
+   p = buffer;
+   pv = buf;
+   do {
+      if (*p == '&') {
+         /* found entity */
+         for(j=0;j<nentity;j++){
+            if(strncmp(p,entity_name[j],strlen(entity_name[j])) == 0){
+               for(k=0;k<(int)strlen(entity_value[j]);k++)
+                  *pv++ = entity_value[j][k];
+               p += strlen(entity_name[j]);
+               break;
+            }
... 27 more lines ...
  99   08 Sep 2005 Ryu SawadaForumDividing xml the definition xml file.
I am thinking to divide my definition xml file into several files.

I do not know if there is a general way, but I found some web pages mentioning about it. According to 
these pages we can include an xml document to  other one like.

---------- booklist.xml ------------
<?xml version="1.0"?>
<!DOCTYPE books [
<!ENTITY book1 SYSTEM "book1.xml">
]>

<books>
  &book1;
</books>
------------------------------------
------------ book1.xml -------------
<?xml version="1.0"?>
<book>
  <title>Title of the book</title>
  <author>Author of the book</author>
</book>
------------------------------------

Is it possible to do it with mxml ?


I have two reasons.
1.
 I have two ROME programs.  I call them as "writer" and "reader" in this message. "reader" reads output 
file from "writer". In this case, "reader" needs to know the structure of branch folder defined in "writer"'s 
xml file.
What I am doing is adding headers of "writer" to DictionaryHeaders in Makefile.user of "reader". At least, 
it works, but this way I have to write reading function of trees by hand. On the other hand, If it is 
possible to include a part of xml file of "writer" in that of "reader", romebuilder can create proper 
functions automatically.

2.
 My project definition file is already big. It has more than 2000 lines. If one has good XML editor, it may 
not be a problem. But unfortunately I do not know good editor on Linux. What I am thinking is making a 
directory structure like this.
.
|-- main_definition.xml
`-- xml
    |-- folders
    |   |-- folder_1.xml
    |   |-- folder_2.xml
    |   `-- folder_3.xml
    `-- tasks
        |-- task_1.xml
        |-- task_2.xml
        `-- task_3.xml

folder_[1-3].xml and task_[1-3].xml will be included in main_definition.xml.
  98   30 Aug 2005 Matthias SchneebeliBug ReportTFile creation and TTree
> When the filename base IO was added, it seems that TFile creation was moved from 
> ROMEEventLoop::DAQInit to ROMEEventLoop:DAQEndOfRun.
> 
> So ROME makes TTrees without outputfile.
> 
> This is dangerous when a TTree becomes huge.
> It can consume large amount of memory.

Your right. I have changed it back.
  97   29 Aug 2005 Ryu SawadaBug ReportTFile creation and TTree
When the filename base IO was added, it seems that TFile creation was moved from 
ROMEEventLoop::DAQInit to ROMEEventLoop:DAQEndOfRun.

So ROME makes TTrees without outputfile.

This is dangerous when a TTree becomes huge.
It can consume large amount of memory.
  96   21 Jul 2005 Ryu SawadaSuggestionAn idea of file I/O
Current file handling of ROME is based on run number. This way is simple and easy to understand. But 
there are some arguments on it.

(i) In case of .mid file. ROME assume the file name is like run00001.mid. But this is not always true. 
MIDAS users can have different name.

(ii) ROME saves one TTree in one file. But there are cases that user want to save several TTrees in a file

(iii) Especially rare event search experiments like MEG, one file may contain signal candidate events 
from several runs.

To solve this issue one idea is to move from run base I/O to filename base I/O.

* Input
Users may specify filename instead of run number with command line option like.
XXXanalyzer.exe -f run00001.mid,run00002.mid

Then ROMEAnalyzer provides information of filename to DAQ class.

How files are handled is depending on DAQ class. Normally each files will be read one by one.
But in case of bartender program, they will be read in parallel to mix.

In case of .mid file, run number is written in run header of files.
ROMEMidas should change current run number at the BeginOfRun.

* Output
For the output filename we can employ same technique as database path.
This way users can use also run number and some other parameters.
And they can store several TTrees in a file.

  <Tree>
      <TreeName>tree</TreeName>
      <TreeOutputFileName>"%s#.root",gAnalyzer->GetGSP()->GetFilePrefix()<TreeOutputFileName>
      <Branch>
        <BranchName>kine</BranchName>
        <RelatedFolder>Kinematics</RelatedFolder>
      </Branch>
  </Tree>
 

This change is quite big, and it affects all ROME users.
We have to discuss enough on it before changing.

(One choice is to remain run number base I/O.)
  95   21 Jul 2005 Ryu SawadaSuggestionResetFolders
> ResetFolders are called in DAQEvent for every events.
> 
> I have some folders who's information have to be kept during the run.
> 
> One possibility is to add new tag like <ResetBoforeEvents> in folder definition.
> The other is give up reset in ROMEEventLoop and give users resposibility of reset.

done.

The name of the tag is <NoResetByFramework>
  94   10 Jul 2005 Ryu SawadaSuggestionResetFolders
ResetFolders are called in DAQEvent for every events.

I have some folders who's information have to be kept during the run.

One possibility is to add new tag like <ResetBoforeEvents> in folder definition.
The other is give up reset in ROMEEventLoop and give users resposibility of reset.
  93   28 Jun 2005 Ryu SawadaBug Reportsupport folder object in folder.
When one makes a support folder type field in folder, pointer to the support folder or pointer of 
TClonesArray is in the folder.
But There is no "new" statement to create the object.
  92   28 Jun 2005 Ryu SawadaSuggestionclass members in TTree
> This is just a matter of favor.
> We sometimes use TTree interactively. At that time, I feel fRunNumber, fEventNumber, fTimeStamp, 
> fSequentialNumber are long to type.
> I prefer shorter without upper case letter.
> If many people agree it, I would like to ask to change them run,event,timestamp,number like MIDAS analyzer.
changed to run, event, time and number.
ELOG V3.1.4-2e1708b5