int main()
{
   Password* fallout = new Password();
   addWords(fallout);
   guessWords(fallout);
   delete fallout;
}
Exemple #2
0
bool findAnchorImpl(int* result, T& dict,
        int nrows, const char** rows,
        const int* lens, int ANCHOR, int last) {
    for (int start = 0; start <= last; start++) {
        if (addWords(result, dict, nrows, rows, lens,
                     ANCHOR, start)) {
            return true;
        }
    }
    return false;
}
// . set words from a string
// . assume no HTML entities in the string "s"
// . s must be NULL terminated
// . NOTE: do not free "s" from under us cuz we reference it
// . break up the string ,"s", into "words".
// . doesn't do tags, only text nodes in "xml"
// . our definition of a word is as close to English as we can get it
// . BUT we also consider a string of punctuation characters to be a word
bool Words::set( char *s, bool computeWordIds ) {
	reset();

	// determine rough upper bound on number of words by counting
	// punct/alnum boundaries
	m_preCount = countWords ( s );
	if ( !allocateWordBuffers( m_preCount ) ) {
		return false;
	}

	return addWords( s, 0x7fffffff, computeWordIds );
}
bool Words::setxi ( char *s , char *buf, long bufSize, long niceness ) {
	// prevent setting with the same string
	if ( m_s == s ) { char *xx=NULL;*xx=0; }
	reset();
	m_version = TITLEREC_CURRENT_VERSION;
	// save for sanity check
	m_s = s;
	m_localBuf2 = buf;
	m_localBufSize2 = bufSize;
	// determine rough upper bound on number of words by counting
	// punct/alnum boundaries
	m_preCount = countWords ( s , niceness );
	if (!allocateWordBuffers(m_preCount)) return false;
	bool computeWordIds = true;
	return addWords(s,0x7fffffff, computeWordIds, niceness );
}
// . set words from a string
// . assume no HTML entities in the string "s"
// . s must be NULL terminated
// . NOTE: do not free "s" from under us cuz we reference it
// . break up the string ,"s", into "words".
// . doesn't do tags, only text nodes in "xml"
// . our definition of a word is as close to English as we can get it
// . BUT we also consider a string of punctuation characters to be a word
bool Words::set ( char *s , long version, 
		  bool computeWordIds ,
		  long niceness ) {

	// prevent setting with the same string
	if ( m_s == s ) { char *xx=NULL;*xx=0; }

	reset();
	m_version = version;
	// save for sanity check
	m_s = s;

	m_version = version;
	// determine rough upper bound on number of words by counting
	// punct/alnum boundaries
	m_preCount = countWords ( s , niceness );
	if (!allocateWordBuffers(m_preCount)) return false;
	
	return addWords(s,0x7fffffff, computeWordIds, niceness );
}
bool Words::set11 ( char *s , char *send , long niceness ) {
	reset();
	m_version = TITLEREC_CURRENT_VERSION;
	m_s = s;
	// this will make addWords() scan for tags
	m_hasTags = true;
	// save it
	char saved = *send;
	// null term
	*send = '\0';
	// determine rough upper bound on number of words by counting
	// punct/alnum boundaries
	m_preCount = countWords ( s , niceness );
	// true = tagIds
	bool status = allocateWordBuffers(m_preCount,true);
	// deal with error now
	if ( ! status ) { *send = saved; return false; }
	// and set the words
	status = addWords(s,0x7fffffff, true, niceness );
	// bring it back
	*send = saved;
	// return error?
	return status;
}
bool Words::set2 ( Xml *xml, 
		   bool computeWordIds ,
		   long niceness) {
	reset();
	m_xml = xml;
	m_version = xml->getVersion();
	m_version = xml->getVersion();
	register char *p = (char *)xml->getContent();
	if ( *p ) p++;
	register long x = 0;
 ploop:
	//if ( is_alnum(*(p-1)) ^ is_alnum(*p) ) x++;
	//if ( is_alnum(*p ) ) x++;
	//x += g_map_is_alpha[*p] ;
	if ( is_alnum_utf8(p) ) x++;
	//if ( isalnum(*p) ) x++;
	//if ( g_map_is_alpha[*p] ) x++;
	//x++;
	p++;
	if ( *p ) goto ploop;

	m_preCount = x;
	m_preCount = xml->getContentLen() / 2;
	//if ( m_preCount > 9000 ) m_preCount = 9000;
	//m_preCount = 9000;

	if (!allocateWordBuffers(m_preCount, true)) return false;
	
	long numNodes = xml->getNumNodes();
	// are we done?
	for ( long k = 0 ; k < numNodes && m_numWords < m_preCount ; k++ ) {
		// get the kth node
		char *node    = xml->getNode   (k);
		long  nodeLen = xml->getNodeLen(k);
		// is the kth node a tag?
		if ( xml->isTag(k) ) {
			m_words         [m_numWords] = node;
			m_wordLens      [m_numWords] = nodeLen;
			m_tagIds        [m_numWords] = xml->getNodeId(k);
			m_wordIds       [m_numWords] = 0LL;
			m_nodes         [m_numWords] = k;
			// we have less than 127 HTML tags, so set 
			// the high bit for back tags
			if ( xml->isBackTag(k)) {
				m_tagIds[m_numWords] |= BACKBIT;
			}

			//log(LOG_DEBUG, "Words: Word %ld: got tag %s%s (%d)", 
			//    m_numWords,
			//    isBackTag(m_numWords)?"/":"",
			//    g_nodes[getTagId(m_numWords)].m_nodeName,
			//    getTagId(m_numWords));

			m_numWords++;
			// used by XmlDoc.cpp
			m_numTags++;
			continue;
		}
		// otherwise it's a text node
		char c = node[nodeLen];
		node[nodeLen] = '\0';
		addWords(node, nodeLen,computeWordIds, niceness);
		node[nodeLen] = c;
	}
	return true;
}
bool Words::set ( Xml *xml, 
		  bool computeWordIds , 
		  long niceness ,
		  long node1 ,
		  long node2 ) {
	// prevent setting with the same string
	if ( m_xml == xml ) { char *xx=NULL;*xx=0; }
	reset();
	m_xml = xml;
	m_version = xml->getVersion();
	//m_version = xml->getVersion();

	// quick test
	if ( ! s_tested ) {
		// only do once
		s_tested = true;
		// set c to a curling quote in unicode
		long c = 0x201c; // 0x235e;
		// encode it into utf8
		char dst[5];
		// point to it
		char *p = dst;
		// put space in there
		*p++ = ' ';
		// "numBytes" is how many bytes it stored into 'dst"
		long numBytes = utf8Encode ( c , p );
		// must be 2 bytes i guess
		if ( numBytes != 3 ) { char *xx=NULL; *xx=0; }
		// check it
		long size = getUtf8CharSize(p);
		if ( size != 3 ) { char *xx=NULL; *xx=0; }
		// is that punct
		if ( ! is_punct_utf8 ( p ) ) { char *xx=NULL;*xx=0; }
		// make sure can pair across
		//unsigned char bits = getPunctuationBits  ( dst , 4 );
		// must be able to pair across
		//if ( ! ( bits & D_CAN_PAIR_ACROSS ) ) { char *xx=NULL;*xx=0;}
	}

	// if xml is empty, bail
	if   ( ! xml->getContent() ) return true;

	long numNodes = xml->getNumNodes();
	if ( numNodes <= 0 ) return true;

	// . can be given a range, if node2 is -1 that means all!
	// . range is half-open: [node1, node2)
	if ( node2 < 0 ) node2 = numNodes;
	// sanity check
	if ( node1 > node2 ) { char *xx=NULL;*xx=0; }
	char *start = xml->getNode(node1);
	char *end   = xml->getNode(node2-1) + xml->getNodeLen(node2-1);
	long  size  = end - start;

	m_preCount = countWords( start , size , niceness );

	// allocate based on the approximate count
	if ( ! allocateWordBuffers(m_preCount, true)) return false;
	
	// are we done?
	for ( long k = node1 ; k < node2 && m_numWords < m_preCount ; k++ ){
		// get the kth node
		char *node    = xml->getNode   (k);
		long  nodeLen = xml->getNodeLen(k);
		// is the kth node a tag?
		if ( ! xml->isTag(k) ) {
			char c = node[nodeLen];
			node[nodeLen] = '\0';
			addWords(node,nodeLen,computeWordIds,niceness);
			node[nodeLen] = c;
			continue;
		}
		// it is a tag
		m_words    [m_numWords] = node;
		m_wordLens [m_numWords] = nodeLen;
		m_tagIds   [m_numWords] = xml->getNodeId(k);
		m_wordIds  [m_numWords] = 0LL;
		m_nodes    [m_numWords] = k;
		// we have less than 127 HTML tags, so set 
		// the high bit for back tags
		if ( xml->isBackTag(k)) {
			m_tagIds[m_numWords] |= BACKBIT;
		}
		//log(LOG_DEBUG, "Words: Word %ld: got tag %s%s (%d)", 
		//    m_numWords,
		//    isBackTag(m_numWords)?"/":"",
		//    g_nodes[getTagId(m_numWords)].m_nodeName,
		//    getTagId(m_numWords));
		
		m_numWords++;
		// used by XmlDoc.cpp
		m_numTags++;
		continue;
	}
	return true;
}
Exemple #9
0
int main(int argc, char *const *argv) {
    FILE *data = NULL;
    struct parameters p;
    char o, *tok, tmp[256];
    word_t word;
    struct d_entry *d_entry;

    p.delimiters = NULL;
    STAILQ_INIT(&p.dictionary);

    // Initialisation des parametres
    while((o = getopt (argc, argv, "a:A:d:D:w:W:hHvV")) != -1)
        switch(o) {
            case 'w':
            case 'W':
                tok = strtok(optarg, " ");
                do {
                    if((d_entry = (struct d_entry *) malloc(sizeof(struct d_entry))))
                        if((d_entry->string = (char *) calloc((strlen(tok) + 1), sizeof(char)))) {
                            strcpy(d_entry->string, tok);
                            STAILQ_INSERT_TAIL(&p.dictionary, d_entry, entries);
                        }
                        else {
                            fprintf(
                                stderr,
                                "%s: Unable to create a dictionary entry for the word \"%s\": %s\n",
                                *argv, tok, strerror(errno)
                            );
                            free(d_entry);
                        }
                    else
                        fprintf(
                            stderr,
                            "%s: Unable to create a dictionary entry for the word \"%s\": %s\n",
                            *argv, tok, strerror(errno)
                        );
                } while((tok = strtok(NULL, " ")));
                break;
            case 'd':
            case 'D':
                p.delimiters = optarg;
                break;
            case 'h':
            case 'H':
                switch(system("cat help.txt")) {
                    case 1:
                        fprintf(stderr, "%s: \"help.txt\" does not exist", *argv);
                    case -1:
                        return EXIT_FAILURE;
                    default:
                        return EXIT_SUCCESS;
                        break;
                }
                break;
            case 'v':
            case 'V':
                verbose = true;
                break;
            case '?':
            default:
                fprintf(stderr, "Usage: %s %s\n", *argv, USAGE);
                return EXIT_FAILURE;
                break;
        }

    // Chargement des dictionnaires
    while(optind < argc - 1) {
        if(!(data = fopen(argv[optind], "r")))
            fprintf(stderr, "%s: %s\n", *argv, strerror(errno));
        else {
            addWords(data, &p.dictionary);
        }
        fclose(data);
        optind++;
    }

    if(optind >= argc) {
        fprintf(stderr, "Usage: %s %s\n", *argv, USAGE);
        return EXIT_FAILURE;
    }

    // Chargement de l'automate
    if(!(data = fopen(argv[optind], "r"))) {
        fprintf(stderr, "%s: %s: %s\n", *argv, argv[optind], strerror(errno));
        return EXIT_FAILURE;
    }
    if(!parse(data, &(p.fsm))) {
        fprintf(stderr, "%s: Unable to parse the automaton file\n", *argv);
        fclose(data);
        return EXIT_FAILURE;
    }
    fclose(data);

    // Lecture de mots sur l'entree standard
    if(STAILQ_EMPTY(&p.dictionary)) {
        while(printf("> "), scanf("%255[^\n]s\n", tmp)) {
            word = mkword(tmp, p.delimiters);
            printf("%s - %srecognized by the automaton\n", tmp, recognize(&p.fsm, word) ? "" : "un");
            wfree(word);
            getchar();
        }
    }

    // Lecture du dictionnaire
    while((d_entry = STAILQ_FIRST(&p.dictionary))) {
        word = mkword(d_entry->string, p.delimiters);
        printf("%s - %srecognized by the automaton\n", d_entry->string, recognize(&p.fsm, word) ? "" : "un");
        wfree(word);
        STAILQ_REMOVE_HEAD(&p.dictionary, entries);
        free(d_entry->string);
        free(d_entry);
    }

    freeFsm(&(p.fsm));
    return EXIT_SUCCESS;
}
bool Words::set( Xml *xml, bool computeWordIds, int32_t node1, int32_t node2 ) {
	// prevent setting with the same string
	if ( m_xml == xml ) gbshutdownLogicError();

	reset();

	m_xml = xml;

	// if xml is empty, bail
	if ( !xml->getContent() ) {
		return true;
	}

	int32_t numNodes = xml->getNumNodes();
	if ( numNodes <= 0 ) {
		return true;
	}

	// . can be given a range, if node2 is -1 that means all!
	// . range is half-open: [node1, node2)
	if ( node2 < 0 ) {
		node2 = numNodes;
	}

	// sanity check
	if ( node1 > node2 ) gbshutdownLogicError();

	char *start = xml->getNode(node1);
	char *end = xml->getNode( node2 - 1 ) + xml->getNodeLen( node2 - 1 );
	int32_t  size  = end - start;

	m_preCount = countWords( start , size );

	// allocate based on the approximate count
	if ( !allocateWordBuffers( m_preCount, true ) ) {
		return false;
	}

	// are we done?
	for ( int32_t k = node1; k < node2 && m_numWords < m_preCount; ++k ) {
		// get the kth node
		char *node = xml->getNode( k );
		int32_t nodeLen = xml->getNodeLen( k );

		// is the kth node a tag?
		if ( !xml->isTag( k ) ) {
			/// @todo ALC why are we adding NULL and restoring it after?
			/// addWords should be change to use nodeLen and not null terminated string
			char c = node[nodeLen];
			node[nodeLen] = '\0';
			addWords( node, nodeLen, computeWordIds );
			node[nodeLen] = c;
			continue;
		}

		// it is a tag
		m_words    [m_numWords] = node;
		m_wordLens [m_numWords] = nodeLen;
		m_tagIds   [m_numWords] = xml->getNodeId(k);
		m_wordIds  [m_numWords] = 0LL;
		m_nodes    [m_numWords] = k;

		// we have less than 127 HTML tags, so set 
		// the high bit for back tags
		if ( xml->isBackTag(k)) {
			m_tagIds[m_numWords] |= BACKBIT;
		}

		m_numWords++;

		// used by XmlDoc.cpp
		m_numTags++;

		continue;
	}

	return true;
}
        DirectionTypePtr Direction::createDirectionType( std::ostream& message, xml::XElementIterator& subIter, xml::XElementIterator& subIterEnd, bool& isSuccess )
        {
            auto directionType = makeDirectionType();
            
            if( subIter == subIterEnd )
            {
                message << "Direction: well thats weird - should not get here" << std::endl;
                isSuccess = false;
                return directionType;
            }
            
            if( subIter->getName() == "wedge" )
            {
                directionType->setChoice( DirectionType::Choice::wedge );
                isSuccess &= directionType->getWedge()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "dashes" )
            {
                directionType->setChoice( DirectionType::Choice::dashes );
                isSuccess &= directionType->getDashes()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "bracket" )
            {
                directionType->setChoice( DirectionType::Choice::bracket );
                isSuccess &= directionType->getBracket()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "pedal" )
            {
                directionType->setChoice( DirectionType::Choice::pedal );
                isSuccess &= directionType->getPedal()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "metronome" )
            {
                directionType->setChoice( DirectionType::Choice::metronome );
                isSuccess &= directionType->getMetronome()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "octave-shift" )
            {
                directionType->setChoice( DirectionType::Choice::octaveShift );
                isSuccess &= directionType->getOctaveShift()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "harp-pedals" )
            {
                directionType->setChoice( DirectionType::Choice::harpPedals );
                isSuccess &= directionType->getHarpPedals()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "damp" )
            {
                directionType->setChoice( DirectionType::Choice::damp );
                isSuccess &= directionType->getDamp()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "damp-all" )
            {
                directionType->setChoice( DirectionType::Choice::dampAll );
                isSuccess &= directionType->getDampAll()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "eyeglasses" )
            {
                directionType->setChoice( DirectionType::Choice::eyeglasses );
                isSuccess &= directionType->getEyeglasses()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "string-mute" )
            {
                directionType->setChoice( DirectionType::Choice::stringMute );
                isSuccess &= directionType->getStringMute()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "scordatura" )
            {
                directionType->setChoice( DirectionType::Choice::scordatura );
                isSuccess &= directionType->getScordatura()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "image" )
            {
                directionType->setChoice( DirectionType::Choice::image );
                isSuccess &= directionType->getImage()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "principal-voice" )
            {
                directionType->setChoice( DirectionType::Choice::principalVoice );
                isSuccess &= directionType->getPrincipalVoice()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "accordion-registration" )
            {
                directionType->setChoice( DirectionType::Choice::accordionRegistration );
                isSuccess &= directionType->getAccordionRegistration()->fromXElement( message, *subIter );
                return directionType;
            }
            
            if( subIter->getName() == "other-direction" )
            {
                directionType->setChoice( DirectionType::Choice::otherDirection );
                isSuccess &= directionType->getOtherDirection()->fromXElement( message, *subIter );
                return directionType;
            }
                
            std::string name = "rehearsal";
            if( subIter->getName() == name )
            {
                directionType->setChoice( DirectionType::Choice::rehearsal );
                bool isFirstSubItemAdded = false;
                
                while( subIter != subIterEnd )
                {
                    if( subIter->getName() != name )
                    {
                        message << "Direction: createDirectionType encountered an unexpected element '" << subIter->getName() << "' while parsing a collection of '" << name << "' elements" << std::endl;
                        isSuccess = false;
                        return directionType;
                    }
                    auto itemToAdd = makeRehearsal();
                    isSuccess &= itemToAdd->fromXElement( message, *subIter );
                    if( !isFirstSubItemAdded && directionType->getRehearsalSet().size() == 1 )
                    {
                        directionType->addRehearsal( itemToAdd );
                        directionType->removeRehearsal( directionType->getRehearsalSet().cbegin() );
                    }
                    else
                    {
                        directionType->addRehearsal( itemToAdd );
                    }
                    isFirstSubItemAdded = true;
                    ++subIter;
                } // end loop
                return directionType;
            } // end rehearsal
            
            
            name = "segno";
            if( subIter->getName() == name )
            {
                directionType->setChoice( DirectionType::Choice::segno );
                bool isFirstSubItemAdded = false;
                
                while( subIter != subIterEnd )
                {
                    if( subIter->getName() != name )
                    {
                        message << "Direction: createDirectionType encountered an unexpected element '" << subIter->getName() << "' while parsing a collection of '" << name << "' elements" << std::endl;
                        isSuccess = false;
                        return directionType;
                    }
                    auto itemToAdd = makeSegno();
                    isSuccess &= itemToAdd->fromXElement( message, *subIter );
                    if( !isFirstSubItemAdded && directionType->getSegnoSet().size() == 1 )
                    {
                        directionType->addSegno( itemToAdd );
                        directionType->removeSegno( directionType->getSegnoSet().cbegin() );
                    }
                    else
                    {
                        directionType->addSegno( itemToAdd );
                    }
                    isFirstSubItemAdded = true;
                    ++subIter;
                } // end loop
                return directionType;
            } // end segno
            
            
            name = "words";
            if( subIter->getName() == name )
            {
                directionType->setChoice( DirectionType::Choice::words );
                bool isFirstSubItemAdded = false;
                
                while( subIter != subIterEnd )
                {
                    if( subIter->getName() != name )
                    {
                        message << "Direction: createDirectionType encountered an unexpected element '" << subIter->getName() << "' while parsing a collection of '" << name << "' elements" << std::endl;
                        isSuccess = false;
                        return directionType;
                    }
                    auto itemToAdd = makeWords();
                    isSuccess &= itemToAdd->fromXElement( message, *subIter );
                    if( !isFirstSubItemAdded && directionType->getWordsSet().size() == 1 )
                    {
                        directionType->addWords( itemToAdd );
                        directionType->removeWords( directionType->getWordsSet().cbegin() );
                    }
                    else
                    {
                        directionType->addWords( itemToAdd );
                    }
                    isFirstSubItemAdded = true;
                    ++subIter;
                } // end loop
                return directionType;
            } // end words
            
            
            name = "coda";
            if( subIter->getName() == name )
            {
                directionType->setChoice( DirectionType::Choice::coda );
                bool isFirstSubItemAdded = false;
                
                while( subIter != subIterEnd )
                {
                    if( subIter->getName() != name )
                    {
                        message << "Direction: createDirectionType encountered an unexpected element '" << subIter->getName() << "' while parsing a collection of '" << name << "' elements" << std::endl;
                        isSuccess = false;
                        return directionType;
                    }
                    auto itemToAdd = makeCoda();
                    isSuccess &= itemToAdd->fromXElement( message, *subIter );
                    if( !isFirstSubItemAdded && directionType->getCodaSet().size() == 1 )
                    {
                        directionType->addCoda( itemToAdd );
                        directionType->removeCoda( directionType->getCodaSet().cbegin() );
                    }
                    else
                    {
                        directionType->addCoda( itemToAdd );
                    }
                    isFirstSubItemAdded = true;
                    ++subIter;
                } // end loop
                return directionType;
            } // end coda
            
            
            name = "dynamics";
            if( subIter->getName() == name )
            {
                directionType->setChoice( DirectionType::Choice::dynamics );
                bool isFirstSubItemAdded = false;
                
                while( subIter != subIterEnd )
                {
                    if( subIter->getName() != name )
                    {
                        message << "Direction: createDirectionType encountered an unexpected element '" << subIter->getName() << "' while parsing a collection of '" << name << "' elements" << std::endl;
                        isSuccess = false;
                        return directionType;
                    }
                    auto itemToAdd = makeDynamics();
                    isSuccess &= itemToAdd->fromXElement( message, *subIter );
                    if( !isFirstSubItemAdded && directionType->getDynamicsSet().size() == 1 )
                    {
                        directionType->addDynamics( itemToAdd );
                        directionType->removeDynamics( directionType->getDynamicsSet().cbegin() );
                    }
                    else
                    {
                        directionType->addDynamics( itemToAdd );
                    }
                    isFirstSubItemAdded = true;
                    ++subIter;
                } // end loop
                return directionType;
            } // end dynamics
            
            
            name = "percussion";
            if( subIter->getName() == name )
            {
                directionType->setChoice( DirectionType::Choice::percussion );
                bool isFirstSubItemAdded = false;
                
                while( subIter != subIterEnd )
                {
                    if( subIter->getName() != name )
                    {
                        message << "Direction: createDirectionType encountered an unexpected element '" << subIter->getName() << "' while parsing a collection of '" << name << "' elements" << std::endl;
                        isSuccess = false;
                        return directionType;
                    }
                    auto itemToAdd = makePercussion();
                    isSuccess &= itemToAdd->fromXElement( message, *subIter );
                    if( !isFirstSubItemAdded && directionType->getPercussionSet().size() == 1 )
                    {
                        directionType->addPercussion( itemToAdd );
                        directionType->removePercussion( directionType->getPercussionSet().cbegin() );
                    }
                    else
                    {
                        directionType->addPercussion( itemToAdd );
                    }
                    isFirstSubItemAdded = true;
                    ++subIter;
                } // end loop
                return directionType;
            } // end percussion

            return directionType;
        }
int main (int argc, char **argv) {
  /* extensions must be allocated in the heap because strsep will mess
     with it inside buildFindCmd */
  char *extensions = (char*)malloc(sizeof(char) * MAXLINELEN); 
  bzero(extensions, MAXLINELEN);
  strcat(extensions, "txt:text");
  char *dir = ".";
  char *output = NULL;
  int i;
  int c;

  if (argc < 2) {
    printf("%s -d <dir> -e <ext1:ext2:...> -o <output>\n", argv[0]);
    exit(1);
  }

  /* opterr = 0;                   /\* Turn off error msgs from getopt *\/ */
     
  while ((c = getopt (argc, argv, "e::d:o::")) != -1)
    switch (c)
      {
      case 'e':
        free(extensions); 
        extensions = optarg;
        break;
      case 'd':
        dir = optarg;
        break;
      case 'o':
        output = optarg;
        break;
      case '?':
        if (optopt == 'e' || optopt == 'd' || optopt == 'o')
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
        else if (isprint (optopt))
          fprintf (stderr, "Unknown option `-%c'.\n", optopt);
        else
          fprintf (stderr,
                   "Unknown option character `\\x%x'.\n",
                   optopt);
        return 1;
      default:
        abort ();
      }
     
  /* fprintf(stderr, "extensions = %s, dir = %s, output = %s\n", */
  /*         extensions, dir, output); */
     
  /* for (i = optind; i < argc; i++) */
  /*   fprintf(stderr, "Non-option argument %s\n", argv[i]); */
  
  char* cmd = buildFindCmd(&extensions, dir);
  char* filelist = exec(cmd);
  char* savedFilelist = filelist;
  free(cmd);

  /* printf("%s", filelist); */

  char** words = (char**)malloc(sizeof(char*) * MAXWORDS);
  unsigned long long int num_words = 0, num_words_turn;
  unsigned long long int threshold = STARTTHRESHOLD;  
  int threshold_hit = 0;
  char *file;
  FILE *f;
  int numFiles = countFilelist(filelist);
  int numFilesDone = 0;
  while ((file = strsep(&filelist, "\n")) != NULL) {
    if (file[0] != '\0') {
      /* fprintf(stderr, "===== Opening %s\n", file); */
      if (isDoc(file)) {
        makeTmpWithStrings(file);
        strcpy(file, "tmpfile");
      }
      f = fopen(file, "r");
      num_words_turn = addWords(f, words+num_words);
      /* fprintf(stderr, "===== Total: %llu - Added %llu words from file %s\n", num_words, num_words_turn, file); */
      fprintf(stderr, "===== Total: %llu                        %d of %d files \r", num_words, numFilesDone, numFiles-1);
      num_words += num_words_turn;
      if (num_words >= MAXWORDS-1) {
        fprintf(stderr, " *********************** Numero maximo de palavras excedido. ***********************\n\n\n");
      }
#ifdef SHRINK
      if (num_words > threshold) { /* Whenever we've got more than THRESHOLD words */
        /* fprintf(stderr, " *********************** Shrinking, Threshold: %llu ***********************\n\n", threshold); */
        num_words = shrink(words, num_words); /* Eliminate duplicates */
        threshold_hit++;
        if (threshold_hit > 2) {
          threshold *= 2;
          threshold_hit = 0;
        }
      }
#endif
      fclose(f);
      numFilesDone++;
    }
  }
  num_words = shrink(words, num_words);
  /* fprintf(stderr, "===== Total words found: %llu\n", num_words); */
  
  qsort(words, num_words, sizeof(char*), compare_case);

  if (output) {
    f = fopen(output, "w");
    for (i = 0; i < num_words; i++) {
      fprintf(f, "%s\n", words[i]);
      free(words[i]);
    }
    fclose(f);
  }
  else {
    for (i = 0; i < num_words; i++) {
      printf("%s\n", words[i]);
      free(words[i]);
    }
  }

  fprintf(stderr, "===== Total words found: %llu\n", num_words);

  free(words);
  free(savedFilelist);
  if (extensions)
    free(extensions);

  return 0;
}