home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1997-1998, Tall Tree Software Co.
- *
- * This code is provided AS-IS, with no warranty expressed or implied.
- * in no way shall Tall Tree Software Co. be held liable for damages
- * brought about by the use of this software.
- */
-
-
- #include <afxwin.h>
-
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include <Rewriter Hook.h>
- #include <StoredObjectSet.h>
-
- #undef IDC_STATIC
- #include "resource.h"
- #include "Settings.h"
-
- // This hook is designed to pull the comments for function/method
- // arguments out of the comment of the function and put them with
- // the parameter. For example, if we have a function like this:
- //
- // /*
- // Description: My Function
- //
- // Arguments:
- // arg1 - This is arg1
- // arg2 - This is arg2
- // ...
- // */
- // void f( int arg1, int arg2 )
- //
- // Without this hook in place, the scanner will report three objects,
- // "f", "f::arg1", and "f::arg2". The comment for arg1 and arg2
- // will be null, but we'll still see a "Arguments" section in the
- // output because the output format is designed to first look for
- // an "Arguments" comment section and only use the comments associated
- // directly with the arguments if the comment section does not exist.
- //
- // The net effect of this hook is to make it appear to DocJet as if the
- // code block looks like this:
- //
- // /*
- // Description: My Function
- //
- // ...
- // */
- // void f( int arg1 /* This is arg1 */, int arg2 /* This is arg2 */ )
- //
- // When DocJet sees a block of code like this, it reports three objects,
- // as before, except that the parameter comments are filled in. The
- // output will be exactly the same as before, because the output format
- // is designed to generate the same thing both ways.
- //
- // The advantage of having your comments directly associated with the
- // parameter is twofold. First, you can detect when parameters aren't
- // documented and second you can use DocJet's knowledge of things like
- // the parameter's declaration in your output.
- //
- //
- // We implement this functionality by snooping on the object stream as
- // it comes back from the scanner, looking for function and parameter
- // objects. When we see a function, we hunt for an "Arguments" section,
- // stash it for future reference, and delete it from the comment.
- // When we see a parameter, we look through our list of stashed
- // function "Arguments" section for the one that belongs to the function
- // this parameter is a part of and then see if we can find the part
- // of the function's arguments section that pertains to this parameter.
- // If we can find such a thing, we use that as the parameter's comment.
- //
- // This fellow implements a settings dialog. The dialog itself is pretty
- // basic (implemented in "Settings.cpp"). We use the settings to store
- // the names of the keywords that introduce sections in the comments.
- //
- // Most folks will be able to use this DLL straight out of the box,
- // but if you have to mess with it, the most likely cause is that
- // we're not correctly recognizing or parsing the arguments section.
- // The function responsible for locating the Arguments section is
- // FindArgumentSection, and it relies heavily on the variables
- // argSectionNames and otherSectionNames. The function that breaks
- // down the argument section is FindArgumentComment.
-
-
-
-
- ///////////////////////////////////////////////////////////////////////
- // Preliminary junk
-
- static HookReportFunction nextOnObjectFound;
-
- extern "C" DLLEXPORT void SetNextOnObjectFound( HookReportFunction onObjectFound )
- {
- nextOnObjectFound = onObjectFound;
- }
-
- ///////////////////////////////////////////////////////////////////////
- // This is the code that stores the argument sections of functions.
- // The data structure is just a simple flat array of FunctionStorage
- // structures. We dynamically grow it using realloc.
-
-
- struct FunctionStorage {
- char *funcname;
- char *argsection;
- char *inputArgSection;
- char *outputArgSection;
- };
-
- static FunctionStorage *storage = 0;
- static int numInStorage = 0;
- static int storageSize = 0;
-
- static char null_comment[] = "";
-
- void AddFunction( const char *name, char *argSection,
- char *inputArgSection, char *outputArgSection )
- {
- if ( storage == 0 ) {
- assert( numInStorage == 0 );
- storageSize = 100;
- storage = (FunctionStorage *)malloc(
- storageSize * sizeof(FunctionStorage) );
- }
- else if ( numInStorage == storageSize ) {
- storageSize *= 2;
- storage = (FunctionStorage *)realloc( storage,
- storageSize * sizeof(FunctionStorage) );
- }
- storage[numInStorage].funcname = strdup( name );
- storage[numInStorage].argsection = argSection;
- storage[numInStorage].inputArgSection = inputArgSection;
- storage[numInStorage].outputArgSection = outputArgSection;
- ++numInStorage;
- }
-
- FunctionStorage *FindArgSection( const char *funname )
- {
- for ( int i = 0; i < numInStorage; ++i )
- if ( 0 == strcmp( storage[i].funcname, funname ) )
- return( storage+i );
- return( 0 );
- }
-
-
-
- ///////////////////////////////////////////////////////////////////////
- // This is the code that breaks out the arguments section(s) of a
- // comment. It does so by looking for lines that start with one
- // of the known comment section names (listed below) and then an
- // end of line character or colon or dash.
- //
- // The function "isSectionStart" is used to discover if a line is a
- // section starter or not. It returns a pointer to the point in the
- // line just past the header. "Sections" will either be argSectionNames,
- // a list of argument section headers or otherSectionNames, which is
- // a list of all the other known section names.
-
-
- char *defaultArgSectionNames[] = { "arguments", "parameters", "args", 0 };
- char *defaultInputArgSectionNames[] = { "input", "inputs",
- "input arguments",
- "input parameters", 0 };
- char *defaultOutputArgSectionNames[] = { "output", "outputs",
- "output arguments",
- "output parameters", 0 };
- char *defaultOtherSectionNames[] = { "Remarks", "Description", "Summary",
- "Function", "Function Name", "Synopsis",
- "Result", "Results", "Returns",
- "Return Value", "Purpose", "Author",
- "Example", "Examples", "Header", "Include",
- "Name", "Function Name", "Samples", "See Also",
- "Modification History", "Log", "Modification Log",
- "Includes", "Required Header", "Required Includes",
- "Settings", "Notes", "Return", "Return Code",
- 0 };
-
- char **argSectionNames = defaultArgSectionNames;
- char **inputArgSectionNames = defaultInputArgSectionNames;
- char **outputArgSectionNames = defaultOutputArgSectionNames;
- char **otherSectionNames = defaultOtherSectionNames;
-
- static const char *isSectionStart( const char *commentLine, char **sections )
- {
- // See if the line starts with one of the strings in sections
- commentLine += strspn( commentLine, " \t" );
- for ( ; *sections != 0; ++sections ) {
- if ( 0 == _strnicmp( commentLine, *sections, strlen(*sections) ) ) {
- const char *sp = commentLine + strlen(*sections);
- sp += strspn( sp, " \t" );
- if ( *sp == ':' || *sp == '\n' ) {
- // Yup, we've got a section here. Let's
- // find the start of the body.
- return( sp+1+strspn(sp+1, " \t\n") );
- }
- }
- }
- return( 0 );
- }
-
- static const char *isArgSectionStart( const char *commentLine, char *& argPart,
- char *&inputArgPart, char *&outputArgPart,
- char **&messWith )
- {
- const char *rc;
- rc = isSectionStart( commentLine, inputArgSectionNames );
- if ( rc != 0 ) {
- messWith = &inputArgPart;
- return rc;
- }
- rc = isSectionStart( commentLine, outputArgSectionNames );
- if ( rc != 0 ) {
- messWith = &outputArgPart;
- return rc;
- }
- rc = isSectionStart( commentLine, argSectionNames );
- if ( rc != 0 ) {
- messWith = &argPart;
- return rc;
- }
- return 0;
- }
-
- // This breaks the comment down into the arguments sections and the
- // sections not to do with arguments. If the comment has no
- // recognizable argument section, it returns false. If it does,
- // it will return true and nonArgPart will point to a malloc'ed
- // string that contains just those parts of the comment not in
- // the arguments section and argPart will point to a malloc'ed
- // string that contains the arguments section(s).
-
- void FindArgumentSection( const char *comment, char *&nonArgPart,
- char *&argPart, char *&inputArgPart,
- char *&outputArgPart )
- {
- nonArgPart = 0;
- argPart = 0;
- inputArgPart = 0;
- outputArgPart = 0;
-
- const char *lastSectionStart = comment;
- const char *s = comment;
- while ( *s != '\0' ) {
- char **messWith;
- const char *nss = isArgSectionStart( s, argPart, inputArgPart,
- outputArgPart, messWith);
- if ( nss != 0 ) {
- if ( s != lastSectionStart ) {
- if ( nonArgPart == 0 ) {
- nonArgPart = (char *)malloc(
- strlen( comment ) + 1 );
- *nonArgPart = '\0';
- }
- char old = *s;
- *(char *)s = '\0';
- strcat( nonArgPart, lastSectionStart );
- *(char *)s = old;
- }
- // Advance s until we find the end or
- // the start of a new section
- s = nss;
- while ( *s != '\0' && 0 == isSectionStart( s, otherSectionNames ) &&
- 0 == isSectionStart( s, argSectionNames ) &&
- 0 == isSectionStart( s, inputArgSectionNames ) &&
- 0 == isSectionStart( s, outputArgSectionNames ) ) {
-
- if ( strchr( s, '\n' ) == 0 )
- s += strlen(s);
- else
- s = 1+strchr( s, '\n' );
- }
- if ( *messWith == 0 ) {
- *messWith = (char *)malloc( strlen(comment)+1 );
- **messWith = '\0';
- }
- char old = *s;
- *(char *)s = '\0';
- strcat( *messWith, nss );
- *(char *)s = old;
- lastSectionStart = s;
- }
- else {
- if ( strchr( s, '\n' ) == 0 )
- s += strlen(s);
- else
- s = 1+strchr( s, '\n' );
- }
- }
- if ( s > lastSectionStart && ( argPart != 0 || inputArgPart != 0 || outputArgPart != 0 ) ) {
- if ( nonArgPart == 0 ) {
- nonArgPart = (char *)malloc(
- strlen( comment ) + 1 );
- *nonArgPart = '\0';
- }
- char old = *s;
- *(char *)s = '\0';
- strcat( nonArgPart, lastSectionStart );
- *(char *)s = old;
- }
- if ( argPart != 0 && nonArgPart == 0 )
- nonArgPart = strdup( "" );
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- // This function hunts down a particular variable's comment within an
- // argument section (which was previously parsed out by
- // FindArgumentSection.
-
- static char *FindArgumentComment( const char *argSection, const char *varname )
- {
- const char *s = argSection;
- int vl = strlen(varname);
- while ( *s != '\0' ) {
- s += strspn( s, " \t" );
- if ( 0 == strncmp( s, varname, vl ) &&
- 0 != strchr( "-=:", s[vl+strspn(s+vl," \t")] ) ) {
- const char *start = s + vl + strspn(s+vl, " \t") + 1;
- start += strspn( start, " \t" );
- s = strchr( start, '\n' );
- if ( s == 0 )
- s = start+strlen(start);
- else
- ++s;
- while ( *s != '\0' ) {
- s += strspn( s, " \t" );
- int fwl = 0;
- while ( isalnum(s[fwl]) || s[fwl] == '_' )
- ++fwl;
- fwl += strspn( s+fwl, " \t" );
- if ( fwl > 0 && 0 != strchr( "-=:", s[fwl] ) )
- break;
- else {
- if ( strchr( s, '\n' ) == 0 )
- s = s+strlen(s);
- else
- s = strchr( s, '\n' )+1;
- }
- }
- char old = *s;
- *(char *)s = '\0';
- start = strdup( start );
- *(char *)s = old;
- return( (char *)start );
- }
- else {
- if ( strchr( s, '\n' ) == 0 )
- s = s+strlen(s);
- else
- s = strchr( s, '\n' )+1;
- }
- }
- return( 0 );
- }
-
- enum ArgDir { Input, Output, Neutral };
-
- static const char *FindTagsInComment( const char *originalComment,
- ArgDir &argDir )
- {
- const char *s = originalComment + strspn( originalComment, " \t\r\n" );
- if ( *s != '[' )
- return originalComment;
-
- ++s;
- s += strspn( s, " \t\r\n" );
- argDir = Neutral;
-
- while ( *s != '\0' ) {
- int l = strcspn( s, " \t\r\n,]" );
- if ( ( l == 2 && 0 == strncmp( s, "in", l ) ) ||
- ( l == 5 && 0 == strncmp( s, "input", l ) ) )
- argDir = Input;
- else if ( ( l == 3 && 0 == strncmp( s, "out", l ) ) ||
- ( l == 6 && 0 == strncmp( s, "output", l ) ) )
- argDir = Output;
- else if ( ( l == 6 && 0 == strncmp( s, "retval", l ) ) )
- argDir = Output; // Maybe argDir = RetVal?
-
- s += l;
- s += strspn( s, " \t\r\n" );
- if ( *s == ']' )
- return s+1+strspn(s+1," \t\r\n");
- else if ( *s == ',' )
- s += 1+strspn( s+1, " \t\r\n" );
- else
- break;
- }
-
- // TODO: Perhaps throw a syntax error here
- argDir = Neutral;
- return originalComment;
- }
-
- static char *FindArgumentComment( FunctionStorage *argSection, const char *varname,
- ArgDir &dir )
- {
- if ( argSection->argsection != 0 ) {
- char *c = FindArgumentComment( argSection->argsection, varname );
- if ( c != 0 ) {
- const char *nc = FindTagsInComment( c, dir );
- if ( nc != c ) {
- char *newC = strdup( nc );
- free( c );
- c = newC;
- }
- return c;
- }
- }
- if ( argSection->inputArgSection != 0 ) {
- char *c = FindArgumentComment( argSection->inputArgSection, varname );
- if ( c != 0 ) {
- dir = Input;
- return c;
- }
- }
- if ( argSection->outputArgSection != 0 ) {
- char *c = FindArgumentComment( argSection->outputArgSection, varname );
- if ( c != 0 ) {
- dir = Output;
- return c;
- }
- }
- return 0;
- }
-
-
-
- static StoredObjectSet parms;
-
- void CheckStoredParms( const char *name )
- {
- unsigned int namelen = strlen(name);
- StoredObjectSet::Iterator i( parms );
- while ( i ) {
- StoredObjectSet::Object &p = *i;
-
- if ( 0 == strncmp( p.objectName, name, namelen ) &&
- ( p.objectName[namelen] == ':' ||
- p.objectName[namelen] == '.' ) ) {
- FunctionStorage *argSection =
- FindArgSection( name );
- assert( argSection != 0 );
-
- ArgDir dir;
- char *comment =
- FindArgumentComment( argSection,
- p.objectName+namelen +
- (p.objectName[namelen] == ':' ? 2 : 1 ), dir );
-
- ExtrasSet xtras( p );
- if ( dir == Input )
- xtras.Set( ATTR_ARGDIR, AV_ARGDIR_BYVAL );
- else if ( dir == Output )
- xtras.Set( ATTR_ARGDIR, AV_ARGDIR_BYREF );
-
- // TODO: Inspect the comment to see if it's got [in]
- // directives.
- (*nextOnObjectFound)( p.sourceFile, p.commentStartLine,
- p.declStartLine, p.objectName, *p.subtype,
- "", p.declaration,
- (comment == 0 ? p.comment : comment),
- p.body, (char const **)p.extras );
- if ( comment != 0 )
- free( comment );
-
- parms.Destroy( i );
- }
- else
- ++i;
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // This is the business end of the thing, it's called by a source
- // file scanner when an object is recognized. Our job is to see
- // if it's a function or parameter, do our magic with the comments,
- // and pass it on.
-
- extern "C" DLLEXPORT void OnObjectFound( const char *p_sourceFile,
- unsigned int p_commentStartLine,
- unsigned int p_declStartLine,
- const char *p_objectName,
- const Subtype &p_subtype,
- const char *p_superclass,
- const char *p_declaration,
- const char *p_comment,
- const char *p_body,
- char const **p_extras )
- {
- assert( nextOnObjectFound != 0 );
-
- ExtrasSet xtras( p_extras );
-
- char *comment = 0;
- if ( p_subtype.roughType == ARGUMENT_ID && *p_comment == '\0' ) {
- // Extract the function name here...
- char *oldp = (char *)p_objectName + strlen(p_objectName);
- while ( oldp > p_objectName &&
- *oldp != '.' &&
- (*oldp != ':' || oldp[1] != ':') )
- --oldp;
- assert( oldp > p_objectName );
- char old = *oldp;
- *oldp = '\0';
- // Look up the argument section of the comment of the
- // function.
- FunctionStorage *argSection = FindArgSection( p_objectName );
- *oldp = old;
- // TODO: If we weren't relying on the fact that functions
- // are always reported before their arguments, we'd need
- // to see if argSection was 0 and, if so, store the
- // parameter for later (when the function actually
- // showed up.)
- if ( argSection == 0 ) {
- assert( p_superclass == 0 || *p_superclass == '\0' );
- parms.Add( new StoredObjectSet::Object
- ( p_sourceFile, p_commentStartLine,
- p_declStartLine, p_objectName, p_subtype,
- p_superclass, p_declaration,
- p_comment, p_body, p_extras ) );
- return;
- }
-
- ArgDir dir;
- comment = FindArgumentComment( argSection,
- oldp + ( *oldp == ':' ? 2 : 1 ), dir );
- // TODO: Look for [in] direction directives.
- if ( dir == Input )
- xtras.Set( ATTR_ARGDIR, AV_ARGDIR_BYVAL );
- else if ( dir == Output )
- xtras.Set( ATTR_ARGDIR, AV_ARGDIR_BYREF );
- }
- else if ( p_subtype.roughType != ARGUMENT_ID ) {
- // If this is a function, store the object name and the
- // argument section of the comment
- char *argPart, *inputArgPart, *outputArgPart;
- FindArgumentSection( p_comment, comment, argPart,
- inputArgPart, outputArgPart );
- AddFunction( p_objectName, argPart, inputArgPart, outputArgPart );
- CheckStoredParms( p_objectName );
- }
- (*nextOnObjectFound)( p_sourceFile, p_commentStartLine,
- p_declStartLine, p_objectName, p_subtype,
- p_superclass, p_declaration,
- (comment == 0 ? p_comment : comment),
- p_body, xtras );
- if ( comment != 0 )
- free( comment );
- }
-
- // All OnScanComplete has to do is clean up our storage.
-
- extern "C" DLLEXPORT void OnScanComplete()
- {
- // TODO: If we weren't relying on the fact that functions are always
- // reported before their arguments, we'd try to figure out the
- // comments for any argument objects we had to punt on here.
-
- // Free all the storage we allocated.
- for ( int i = 0; i < numInStorage; ++i ) {
- free( storage[i].funcname );
- if ( storage[i].argsection != 0 )
- free( storage[i].argsection );
- if ( storage[i].inputArgSection != 0 )
- free( storage[i].inputArgSection );
- if ( storage[i].outputArgSection != 0 )
- free( storage[i].outputArgSection );
- }
- free( storage );
-
- parms.PassAll( nextOnObjectFound );
-
- // Let's be anal...
- storage = 0;
- numInStorage = 0;
- storageSize = 0;
- }
-
-
-
-
- extern "C" DLLEXPORT void UseSettings( const void *data, unsigned int dataLen )
- {
- unsigned int n;
- char **sp;
-
- if ( argSectionNames != defaultArgSectionNames ) {
- n = 1;
- for ( sp = argSectionNames; *sp != 0; ++sp ) {
- free( *sp );
- ++n;
- }
- delete[n] argSectionNames;
- }
- if ( inputArgSectionNames != defaultInputArgSectionNames ) {
- n = 1;
- for ( sp = inputArgSectionNames; *sp != 0; ++sp ) {
- free( *sp );
- ++n;
- }
- delete[n] inputArgSectionNames;
- }
- if ( outputArgSectionNames != defaultOutputArgSectionNames ) {
- n = 1;
- for ( sp = outputArgSectionNames; *sp != 0; ++sp ) {
- free( *sp );
- ++n;
- }
- delete[n] outputArgSectionNames;
- }
- if ( otherSectionNames != defaultOtherSectionNames ) {
- n = 1;
- for ( sp = otherSectionNames; *sp != 0; ++sp ) {
- free( *sp );
- ++n;
- }
- delete[n] otherSectionNames;
- }
-
- if ( data == 0 ) {
- argSectionNames = defaultArgSectionNames;
- otherSectionNames = defaultOtherSectionNames;
- return;
- }
-
- if ( *(int *)data < 0 || *(int *)data > 1 ) {
- // Something's wrong with the data.
- MessageBox( 0, "Bogus data passed to Argument Hook.UseSettings!", "Error", MB_OK );
- return;
- }
-
- int version = *(int *)data;
- const char *oss = ((const char *)data) + sizeof(int);
-
- n = 1;
- for ( const char *s = oss; *s != '\0'; s += strlen(s)+1 )
- ++n;
-
- argSectionNames = new char*[n];
- sp = argSectionNames;
- for ( s = oss; *s != '\0'; s += strlen(s)+1 )
- *sp++ = strdup(s);
- *sp = 0;
- oss = s+1;
-
- n = 1;
- for ( s = oss; *s != '\0'; s += strlen(s)+1 )
- ++n;
-
- otherSectionNames = new char*[n];
- sp = otherSectionNames;
- for ( s = oss; *s != '\0'; s += strlen(s)+1 )
- *sp++ = strdup(s);
- *sp = 0;
-
- oss = s+1;
-
- if ( version == 0 ) {
- int inputs = 0;
- int outputs = 0;
- int others = 0;
- for ( sp = argSectionNames; *sp != 0; ++sp ) {
- if ( 0 == _strnicmp( *sp, "input", 5 ) )
- ++inputs;
- else if ( 0 == _strnicmp( *sp, "output", 6 ) )
- ++outputs;
- else
- ++others;
- }
- inputArgSectionNames = new char*[inputs+1];
- outputArgSectionNames = new char*[outputs+1];
- char **newArgSectionNames = new char*[others+1];
- inputs = outputs = others = 0;
- for ( sp = argSectionNames; *sp != 0; ++sp ) {
- if ( 0 == _strnicmp( *sp, "input", 5 ) )
- inputArgSectionNames[inputs++] = *sp;
- else if ( 0 == _strnicmp( *sp, "output", 6 ) )
- outputArgSectionNames[outputs++] = *sp;
- else
- newArgSectionNames[others++] = *sp;
- inputArgSectionNames[inputs] = 0;
- outputArgSectionNames[outputs] = 0;
- newArgSectionNames[others] = 0;
- delete[inputs+outputs+others+1] argSectionNames;
- argSectionNames = newArgSectionNames;
- }
- }
- else {
- n = 1;
- for ( s = oss; *s != '\0'; s += strlen(s)+1 )
- ++n;
-
- inputArgSectionNames = new char*[n];
- sp = inputArgSectionNames;
- for ( s = oss; *s != '\0'; s += strlen(s)+1 )
- *sp++ = strdup(s);
- *sp = 0;
- oss = s+1;
-
- n = 1;
- for ( s = oss; *s != '\0'; s += strlen(s)+1 )
- ++n;
-
- outputArgSectionNames = new char*[n];
- sp = outputArgSectionNames;
- for ( s = oss; *s != '\0'; s += strlen(s)+1 )
- *sp++ = strdup(s);
- *sp = 0;
- oss = s+1;
- }
- }
-
- static char *splat( const char *from, char *to )
- {
- from += strspn( from, "\r\n\t ," );
- while ( *from != '\0' ) {
- if ( *from == ' ' || *from == '\t' ||
- *from == '\r' || *from == '\n' ) {
- from += strspn( from, " \t\r\n" );
- if ( *from == ',' ) {
- *to++ = '\0';
- ++from;
- from += strspn( from, ", \r\n" );
- }
- else if ( *from == '\0' ) {
- // good enuf
- }
- else {
- *to++ = ' ';
- }
- }
- else if ( *from == ',' ) {
- *to++ = '\0';
- ++from;
- from += strspn( from, ", \t\r\n" );
- }
- else {
- *to++ = *from++;
- }
- }
- if ( to[-1] != '\0' )
- *to++ = '\0';
- *to++ = '\0';
- return( to );
- }
-
- extern "C" DLLEXPORT void *ShowSettingsDialog( unsigned int &dataLen )
- {
- AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
-
- CSettings dlg;
- char **sp;
- for ( sp = argSectionNames; *sp != '\0'; ++sp ) {
- if ( dlg.m_arg_sections.GetLength() != 0 )
- dlg.m_arg_sections += ", ";
- dlg.m_arg_sections += *sp;
- }
- for ( sp = inputArgSectionNames; *sp != '\0'; ++sp ) {
- if ( dlg.m_input_arg_sections.GetLength() != 0 )
- dlg.m_input_arg_sections += ", ";
- dlg.m_input_arg_sections += *sp;
- }
- for ( sp = outputArgSectionNames; *sp != '\0'; ++sp ) {
- if ( dlg.m_output_arg_sections.GetLength() != 0 )
- dlg.m_output_arg_sections += ", ";
- dlg.m_output_arg_sections += *sp;
- }
- for ( sp = otherSectionNames; *sp != '\0'; ++sp ) {
- if ( dlg.m_other_sections.GetLength() != 0 )
- dlg.m_other_sections += ", ";
- dlg.m_other_sections += *sp;
- }
-
- if ( IDOK == dlg.DoModal() ) {
- char *rc = (char *)malloc( 4 + dlg.m_arg_sections.GetLength() +
- dlg.m_other_sections.GetLength() +
- dlg.m_input_arg_sections.GetLength() +
- dlg.m_output_arg_sections.GetLength() +
- sizeof(int) );
- *(int *)rc = 1;
- char *n = rc + sizeof(int);
- n = splat( dlg.m_arg_sections, n );
- n = splat( dlg.m_other_sections, n );
- n = splat( dlg.m_input_arg_sections, n );
- n = splat( dlg.m_output_arg_sections, n );
- dataLen = n - rc;
-
- UseSettings( rc, dataLen );
-
- return( rc );
- }
- else
- return( 0 );
- }
-
-