[HEADERS]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Fri, 12 Mar 2010 23:16:29 +0000 (23:16 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Fri, 12 Mar 2010 23:16:29 +0000 (23:16 +0000)
Reintegrate header-work branch. Thanks to hours of boring work on the ddk headers (Most of it done by Amine Khaldi), we have now a decent set, which is still incomplete but already relatively close to latest WDK. A clean rebuild is recommended.

svn path=/trunk/; revision=46155

113 files changed:
1  2 
reactos/ReactOS-generic.rbuild
reactos/ReactOS-i386.rbuild
reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
reactos/boot/freeldr/freeldr/freeldr_base.rbuild
reactos/boot/freeldr/freeldr/include/freeldr.h
reactos/boot/freeldr/freeldr/include/ntoskrnl.h
reactos/dll/win32/kernel32/file/create.c
reactos/drivers/base/beep/beep.c
reactos/drivers/base/bootvid/precomp.h
reactos/drivers/base/kdcom/i386/kdbg.c
reactos/drivers/battery/battc/battc.c
reactos/drivers/battery/battc/battc.h
reactos/drivers/filesystems/fastfat/fsctl.c
reactos/drivers/storage/class/ramdisk/ramdisk.c
reactos/drivers/storage/floppy/floppy.c
reactos/drivers/storage/ide/uniata/ntddk_ex.h
reactos/drivers/wmi/wmilib.c
reactos/hal/halppc/generic/fmutex.c
reactos/hal/halx86/generic/sysinfo.c
reactos/hal/halx86/hal.rbuild
reactos/hal/halx86/hal_generic.rbuild
reactos/hal/halx86/hal_generic_mp.rbuild
reactos/hal/halx86/hal_generic_up.rbuild
reactos/hal/halx86/halmps.rbuild
reactos/hal/halx86/halxbox.rbuild
reactos/hal/halx86/include/bus.h
reactos/hal/halx86/include/hal.h
reactos/include/crt/_mingw.h
reactos/include/crt/crtdefs.h
reactos/include/crt/excpt.h
reactos/include/crt/fpieee.h
reactos/include/crt/io.h
reactos/include/crt/math.h
reactos/include/crt/rtcapi.h
reactos/include/crt/setjmp.h
reactos/include/crt/stddef.h
reactos/include/crt/stdint.h
reactos/include/crt/stdio.h
reactos/include/crt/stdlib.h
reactos/include/crt/tchar.h
reactos/include/crt/time.h
reactos/include/crt/vadefs.h
reactos/include/crt/wchar.h
reactos/include/crt/yvals.h
reactos/include/ddk/bdasup.h
reactos/include/ddk/d3dhal.h
reactos/include/ddk/d3dnthal.h
reactos/include/ddk/ddkmapi.h
reactos/include/ddk/ddrawi.h
reactos/include/ddk/ddrawint.h
reactos/include/ddk/dmemmgr.h
reactos/include/ddk/hubbusif.h
reactos/include/ddk/ide.h
reactos/include/ddk/minitape.h
reactos/include/ddk/ndis.h
reactos/include/ddk/ntdddisk.h
reactos/include/ddk/ntddk.h
reactos/include/ddk/ntifs.h
reactos/include/ddk/ntpoapi.h
reactos/include/ddk/stdunk.h
reactos/include/ddk/strmini.h
reactos/include/ddk/tdikrnl.h
reactos/include/ddk/usbbusif.h
reactos/include/ddk/usbdlib.h
reactos/include/ddk/usbdrivr.h
reactos/include/ddk/usbkern.h
reactos/include/ddk/usbprint.h
reactos/include/ddk/usbprotocoldefs.h
reactos/include/ddk/usbscan.h
reactos/include/ddk/usbstorioctl.h
reactos/include/ddk/wdm.h
reactos/include/ddk/wmlib.h
reactos/include/ndk/cmtypes.h
reactos/include/ndk/exfuncs.h
reactos/include/ndk/i386/ketypes.h
reactos/include/ndk/ifssupp.h
reactos/include/ndk/iotypes.h
reactos/include/ndk/obfuncs.h
reactos/include/ndk/rtlfuncs.h
reactos/include/psdk/batclass.h
reactos/include/psdk/dpfilter.h
reactos/include/psdk/ktmtypes.h
reactos/include/psdk/ntddkbd.h
reactos/include/psdk/ntdef.h
reactos/include/psdk/sdkddkver.h
reactos/include/psdk/usb.h
reactos/include/psdk/usb100.h
reactos/include/psdk/usb200.h
reactos/include/psdk/usbcamdi.h
reactos/include/psdk/usbdi.h
reactos/include/psdk/usbioctl.h
reactos/include/psdk/usbiodef.h
reactos/include/psdk/usbrpmif.h
reactos/include/psdk/usbuser.h
reactos/include/psdk/winbase.h
reactos/include/psdk/windef.h
reactos/include/psdk/winnt.h
reactos/include/psdk/winternl.h
reactos/lib/rtl/nls.c
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/include/internal/ntoskrnl.h
reactos/ntoskrnl/include/internal/trap_x.h
reactos/ntoskrnl/include/ntoskrnl.h
reactos/ntoskrnl/io/iomgr/irp.c
reactos/ntoskrnl/ke/eventobj.c
reactos/ntoskrnl/ke/except.c
reactos/ntoskrnl/ke/i386/traphdlr.c
reactos/ntoskrnl/ke/i386/v86vdm.c
reactos/ntoskrnl/ke/wait.c
reactos/ntoskrnl/ntoskrnl-generic.rbuild
reactos/ntoskrnl/ntoskrnl.pspec
reactos/tools/hpp/hpp.c
reactos/tools/tools.rbuild

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,e03f19e..e03f19e
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,0483738..0483738
mode 000000,100644..100644
--- /dev/null
Simple merge
index 0000000,e1a27b6..e1a27b6
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
index 0000000,9a25a1b..9a25a1b
mode 000000,100644..100644
--- /dev/null
Simple merge
index 0000000,5e71ae3..5e71ae3
mode 000000,100644..100644
--- /dev/null
Simple merge
index 0000000,98b8575..98b8575
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,912549b..912549b
mode 000000,100644..100644
--- /dev/null
index 0000000,77cf578..77cf578
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,ad021d1..ad021d1
mode 000000,100644..100644
--- /dev/null
index 0000000,31d7773..31d7773
mode 000000,100644..100644
--- /dev/null
index 0000000,014b029..014b029
mode 000000,100644..100644
--- /dev/null
index 0000000,69541cb..69541cb
mode 000000,100644..100644
--- /dev/null
Simple merge
index 0000000,c6ee0c4..c6ee0c4
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index ef75198,0000000..1591e48
mode 100644,000000..100644
--- /dev/null
@@@ -1,517 -1,0 +1,540 @@@
-       if (file != NULL)
 +/*
 + * COPYRIGHT:             See COPYING in the top level directory
 + * PROJECT:               Header preprocessor
 + * PURPOSE:               Generates header files from other header files
 + * PROGRAMMER;            Timo Kreuzer
 + *
 + */
 +
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <stdarg.h>
 +#include <string.h>
 +#include <ctype.h>
 +
++//#define DBG 1
++
 +#if DBG
 +#define trace printf
 +#else
 +#define trace if (0) printf
 +#endif
 +
 +typedef struct _DEFINE
 +{
 +    struct _DEFINE *pNext;
 +    int len;
 +    int val;
 +    char szName[1];
 +} DEFINE, *PDEFINE;
 +
 +DEFINE *gpDefines = 0;
 +int iLine;
 +const char *gpszCurFile;
 +
 +char*
 +convert_path(const char* origpath)
 +{
 +      char* newpath;
 +      int i;
 +
 +      newpath = strdup(origpath);
 +
 +      i = 0;
 +      while (newpath[i] != 0)
 +      {
 +#ifdef UNIX_PATHS
 +              if (newpath[i] == '\\')
 +              {
 +                      newpath[i] = '/';
 +              }
 +#else
 +#ifdef DOS_PATHS
 +              if (newpath[i] == '/')
 +              {
 +                      newpath[i] = '\\';
 +              }
 +#endif
 +#endif
 +              i++;
 +      }
 +      return(newpath);
 +}
 +
 +char*
 +GetFolder(const char* pszFullPath)
 +{
 +    return ".";
 +}
 +
 +void*
 +LoadFile(const char* pszFileName, size_t* pFileSize)
 +{
 +      FILE* file;
 +      void* pFileData = NULL;
++      int iFileSize;
++
++    trace("Loading file...");
 +
 +      file = fopen(pszFileName, "rb");
-               fseek(file, 0L, SEEK_END);
-               *pFileSize = ftell(file);
-               fseek(file, 0L, SEEK_SET);
-               pFileData = malloc(*pFileSize);
-               if (pFileData != NULL)
-               {
-                       if (*pFileSize != fread(pFileData, 1, *pFileSize, file))
-                       {
-                               free(pFileData);
-                               pFileData = NULL;
-                       }
-               }
-               fclose(file);
++      if (!file)
 +      {
-         error("Usage: hc <inputfile> <outputfile>\n");
++          trace("Could not open file\n");
++          return NULL;
 +      }
++
++    fseek(file, 0L, SEEK_END);
++    iFileSize = ftell(file);
++    fseek(file, 0L, SEEK_SET);
++    *pFileSize = iFileSize;
++    trace("ok. Size is %d\n", iFileSize);
++
++    pFileData = malloc(iFileSize + 1);
++
++    if (pFileData != NULL)
++    {
++        if (iFileSize != fread(pFileData, 1, iFileSize, file))
++        {
++            free(pFileData);
++            pFileData = NULL;
++        }
++    }
++    else
++    {
++        trace("Could not allocate memory for file\n");
++    }
++
++    fclose(file);
++
 +      return pFileData;
 +}
 +
 +
 +int
 +error(char *format, ...)
 +{
 +    va_list valist;
 +    int res;
 +    va_start(valist, format);
 +    res = vfprintf(stderr, format, valist);
 +    va_end(valist);
 +    return res;
 +}
 +
 +char*
 +GetNextChar(const char *psz)
 +{
 +    while (*psz == ' ' || *psz == '\t') psz++;
 +    return (char*)psz;
 +}
 +
 +char*
 +GetNextLine(char *pszLine)
 +{
 +    /* Walk to the end of the line */
 +    while (*pszLine != 13 && *pszLine != 10 && *pszLine != 0) pszLine++;
 +
 +    /* Skip one CR/LF */
 +    if (pszLine[0] == 13 && pszLine[1] == 10)
 +        pszLine += 2;
 +    else if (pszLine[0] == 13 || pszLine[0] == 10)
 +        pszLine++;
 +
 +    if (*pszLine == 0)
 +    {
 +        return 0;
 +    }
 +
 +    return pszLine;
 +}
 +
 +int
 +strxlen(const char *psz)
 +{
 +    int len = 0;
 +    while (isalnum(*psz) || *psz == '_')
 +    {
 +        psz++;
 +        len++;
 +    }
 +    return len;
 +}
 +
 +
 +void
 +WriteLine(char *pszLine, FILE *fileOut)
 +{
 +    char * pszEnd;
 +
 +    pszEnd = strchr(pszLine, '\n');
 +    if (pszEnd)
 +    {
 +        int len = pszEnd - pszLine + 1;
 +        fwrite(pszLine, 1, len, fileOut);
 +    }
 +}
 +
 +int
 +EvaluateConstant(const char *p, char **pNext)
 +{
 +    PDEFINE pDefine;
 +    int len;
 +
 +    len = strxlen(p);
 +    if (pNext)
 +        *pNext = (char*)p + len;
 +
 +    /* search for the define in the global list */
 +    pDefine = gpDefines;
 +    while (pDefine != 0)
 +    {
 +        trace("found a define: %s\n", pDefine->szName);
 +        if (pDefine->len == len)
 +        {
 +            if (strncmp(p, pDefine->szName, len) == 0)
 +            {
 +                return pDefine->val;
 +            }
 +        }
 +        pDefine = pDefine->pNext;
 +    }
 +    return 0;
 +}
 +
 +int
 +EvaluateExpression(char *pExpression, char **pNext)
 +{
 +    char *p, *pstart;
 +    int inv, thisval, val = 0;
 +
 +    trace("evaluating expression\n");
 +
 +    pstart = GetNextChar(pExpression);
 +    if (*pstart != '(')
 +    {
 +        error("Parse error: expected '(' \n");
 +        return -1;
 +    }
 +
 +    while (1)
 +    {
 +        /* Get the start of the real expression */
 +        p = pstart;
 +        if ((p[0] == '&' && p[1] == '&') ||
 +            (p[0] == '|' && p[1] == '|'))
 +        {
 +            p++;
 +        }
 +        p = GetNextChar(p + 1);
 +
 +        /* Check for inversion modifier */
 +        if (*p == '!')
 +        {
 +            inv = 1;
 +            p = GetNextChar(p + 1);
 +        }
 +        else
 +            inv = 0;
 +
 +        /* Beginning of a new subexpression? */
 +        if (*p == '(')
 +        {
 +            /* Evaluate subexpression */
 +            thisval = EvaluateExpression(p, &p);
 +        }
 +        else if (isdigit(*p))
 +        {
 +            thisval = strtod(p, &p);
 +            trace("found a num: %d\n", thisval);
 +        }
 +        else if (isalpha(*p) || *p == '_')
 +        {
 +            thisval = EvaluateConstant(p, &p);
 +        }
 +        else
 +        {
 +            error("..Parse error, expected '(' or constant in line %d\n",
 +                  iLine);
 +            return -1;
 +        }
 +
 +        if (inv)
 +            thisval = !thisval;
 +
 +        /* Check how to combine the current value */
 +        if (pstart[0] == '(')
 +        {
 +            val = thisval;
 +        }
 +        else if (pstart[0] == '&' && pstart[1] == '&')
 +        {
 +            val = val && thisval;
 +        }
 +        else if (pstart[0] == '&' && pstart[1] != '&')
 +        {
 +            val = val & thisval;
 +        }
 +        else if (pstart[0] == '|' && pstart[1] == '|')
 +        {
 +            trace("found || val = %d, thisval = %d\n", val, thisval);
 +            val = val || thisval;
 +        }
 +        else if (pstart[0] == '|' && pstart[1] != '|')
 +        {
 +            val = val | thisval;
 +        }
 +        else if (pstart[0] == '+')
 +        {
 +            val = val + thisval;
 +        }
 +        else
 +        {
 +            error("+Parse error: expected '(' or operator in Line %d, got %c\n", 
 +                  iLine, pstart[0]);
 +            return -1;
 +        }
 +
 +        p = GetNextChar(p);
 +
 +        /* End of current subexpression? */
 +        if (*p == ')')
 +        {
 +            if (pNext)
 +            {
 +                *pNext = p + 1;
 +            }
 +            return val;
 +        }
 +
 +        /* Continue with a new start position */
 +        pstart = p;
 +    }
 +
 +    return val;
 +}
 +
 +int
 +ParseInputFile(const char *pszInFile, FILE *fileOut)
 +{
 +    char* pInputData, *pCurrentLine, *p1, *p2;
 +    size_t cbInFileLenth, len;
 +    int iIfLevel, iCopyLevel;
 +
 +    trace("parsing input file: %s\n", pszInFile);
 +
 +    /* Set the global file name */
 +    gpszCurFile = pszInFile;
 +
 +    /* Load the input file into memory */
 +    pInputData = LoadFile(pszInFile, &cbInFileLenth);
 +    if (!pInputData)
 +    {
 +        error("Could not load input file %s\n", pszInFile);
 +        return -1;
 +    }
 +
 +    /* Zero terminate the file */
 +    pInputData[cbInFileLenth] = 0;
 +
 +    pCurrentLine = pInputData;
 +    iLine = 1;
 +    iCopyLevel = iIfLevel = 0;
 +
 +    /* The main processing loop */
 +    do
 +    {
 +        trace("line %d: ", iLine);
 +
 +        /* If this is a normal line ... */
 +        if (pCurrentLine[0] != '$')
 +        {
 +            /* Check if we are to copy this line */
 +            if (iCopyLevel == iIfLevel)
 +            {
 +                trace("copying\n");
 +                WriteLine(pCurrentLine, fileOut);
 +            }
 +            else
 +                trace("skipping\n");
 +
 +            /* Continue with next line */
 +            continue;
 +        }
 +
 +        /* Check for $endif */
 +        if (strncmp(pCurrentLine, "$endif", 6) == 0)
 +        {
 +            trace("found $endif\n");
 +            if (iIfLevel <= 0)
 +            {
 +                error("Parse error: $endif without $if in %s:%d\n", pszInFile, iLine);
 +                return -1;
 +            }
 +            if (iCopyLevel == iIfLevel)
 +            {
 +                iCopyLevel--;
 +            }
 +            iIfLevel--;
 +
 +            /* Continue with next line */
 +            continue;
 +        }
 +
 +        /* The rest is only parsed when we are in a true block */
 +        if (iCopyLevel < iIfLevel)
 +        {
 +            trace("skipping\n");
 +
 +            /* Continue with next line */
 +            continue;
 +        }
 +
 +        /* Check for $define */
 +        if (strncmp(pCurrentLine, "$define", 7) == 0)
 +        {
 +            PDEFINE pDefine;
 +
 +            trace("found $define\n");
 +            p1 = GetNextChar(pCurrentLine + 7);
 +            if (*p1 != '(')
 +            {
 +                error("Parse error: expected '(' at %s:%d\n", 
 +                      pszInFile, iLine);
 +                return -1;
 +            }
 +            p1 = GetNextChar(p1 + 1);
 +            len = strxlen(p1);
 +            p2 = p1 + len;
 +            if (*p2 != ')')
 +            {
 +                error("Parse error: expected ')' at %s:%d\n",
 +                      pszInFile, iLine);
 +                return -1;
 +            }
 +
 +            /* Insert the new define into the global list */
 +            pDefine = malloc(sizeof(DEFINE) + len);
 +            strncpy(pDefine->szName, p1, len);
 +            pDefine->szName[len] = 0;
 +            pDefine->len = len;
 +            pDefine->val = 1;
 +            pDefine->pNext = gpDefines;
 +            gpDefines = pDefine;
 +        }
 +
 +        /* Check for $if */
 +        else if (strncmp(pCurrentLine, "$if", 3) == 0)
 +        {
 +            int val;
 +
 +            trace("found $if\n");
 +            /* Increase the if-level */
 +            iIfLevel++;
 +
 +            /* Get beginning of the expression */
 +            p1 = GetNextChar(pCurrentLine + 3);
 +
 +            /* evaluate the expression */
 +            val = EvaluateExpression(p1, 0);
 +
 +            if (val)
 +            {
 +                iCopyLevel = iIfLevel;
 +            }
 +            else if (val == -1)
 +            {
 +                /* Parse error */
 +                return -1;
 +            }
 +        }
 +
 +        /* Check for $include */
 +        else if (strncmp(pCurrentLine, "$include", 8) == 0)
 +        {
 +            int ret;
 +
 +            trace("found $include\n");
 +            p1 = GetNextChar(pCurrentLine + 8);
 +            if (*p1 != '(')
 +            {
 +                error("Parse error: expected '(' at %s:%d, found '%c'\n", 
 +                      pszInFile, iLine, *p1);
 +                return -1;
 +            }
 +            p1++;
 +            p2 = strchr(p1, ')');
 +            *p2 = 0;
 +
 +            /* Parse the included file */
 +            ret = ParseInputFile(p1, fileOut);
 +
 +            /* Restore the global file name */
 +            gpszCurFile = pszInFile;
++            
++            /* Restore the zeroed character */
++            *p2 = ')';
 +
 +            if (ret == -1)
 +            {
 +                return -1;
 +            }
 +        }
 +
 +        /* Check for $$ comment */
 +        else if (strncmp(pCurrentLine, "$$", 2) == 0)
 +        {
 +            trace("$$ ignored\n");
 +            /* continue with next line */
 +            continue;
 +        }
 +
 +        else
 +        {
 +            trace("wot:%s\n", pCurrentLine);
 +        }
 +
 +        /* Continue with next line */
 +    }
 +    while (pCurrentLine = GetNextLine(pCurrentLine),
 +           iLine++,
 +           pCurrentLine != 0);
 +
 +    /* Free the file data */
 +    free(pInputData);
 +
++    trace("Done with file.\n\n");
++
 +    return 0;
 +}
 +
 +
 +int
 +main(int argc, char* argv[])
 +{
 +    char *pszInFolder, *pszInFile, *pszOutFile;
 +    FILE* fileOut;
 +    int ret;
 +
 +    if (argc != 3)
 +    {
++        error("Usage: hpp <inputfile> <outputfile>\n");
 +        exit(1);
 +    }
 +
 +    pszInFile = convert_path(argv[1]);
 +    pszOutFile = convert_path(argv[2]);
 +    pszInFolder = GetFolder(pszInFile);
 +
 +    fileOut = fopen(pszOutFile, "wb");
 +    if (fileOut == NULL)
 +    {
 +        error("Cannot open output file %s", pszOutFile);
 +        exit(1);
 +    }
 +
 +    ret = ParseInputFile(pszInFile, fileOut);
 +
 +    fclose(fileOut);
 +
 +    return ret;
 +}
index 715e773,0000000..2681dbf
mode 100644,000000..100644
--- /dev/null
@@@ -1,46 -1,0 +1,49 @@@
 +<?xml version="1.0"?>
 +<!DOCTYPE group SYSTEM "../tools/rbuild/project.dtd">
 +<group xmlns:xi="http://www.w3.org/2001/XInclude">
 +<directory name="cabman">
 +      <xi:include href="cabman/cabman.rbuild" />
 +</directory>
 +<directory name="cdmake">
 +      <xi:include href="cdmake/cdmake.rbuild" />
 +</directory>
++<directory name="hpp">
++      <xi:include href="hpp/hpp.rbuild" />
++</directory>
 +<directory name="kbdtool">
 +      <xi:include href="kbdtool/kbdtool.rbuild" />
 +</directory>
 +<directory name="nandflash">
 +      <xi:include href="nandflash/nandflash.rbuild" />
 +</directory>
 +<directory name="mkhive">
 +      <xi:include href="mkhive/mkhive.rbuild" />
 +</directory>
 +<directory name="rgenstat">
 +      <xi:include href="rgenstat/rgenstat.rbuild" />
 +</directory>
 +<directory name="unicode">
 +      <xi:include href="unicode/unicode.rbuild" />
 +</directory>
 +<directory name="widl">
 +      <xi:include href="widl/widl.rbuild" />
 +</directory>
 +<directory name="winebuild">
 +      <xi:include href="winebuild/winebuild.rbuild" />
 +</directory>
 +<directory name="wmc">
 +      <xi:include href="wmc/wmc.rbuild" />
 +</directory>
 +<directory name="wpp">
 +      <xi:include href="wpp/wpp.rbuild" />
 +</directory>
 +<directory name="wrc">
 +      <xi:include href="wrc/wrc.rbuild" />
 +</directory>
 +<directory name="utf16le">
 +      <xi:include href="utf16le/utf16le.rbuild" />
 +</directory>
 +<directory name="rbuild_helper">
 +      <xi:include href="rbuild_helper/rbuild_helper.rbuild" />
 +</directory>
 +</group>