Esempio n. 1
0
int main(int argc, char *argv[])
{
    int ret;

    ret = open_File(argc, argv);
    if (ret != 0)
        return E_INTERN;

    //init symbol table
    symbol_table = table_init(DEFAULT_TABLE_SIZE);
    if (symbol_table == NULL) {
        close_File();
        return E_INTERN;
    }

    //init token (init string in token)
    ret = stringInit(&token.attr.lit_string_or_id);
    if (ret != STR_OPERATION_OK) {
        close_File();
        table_destroy(symbol_table);
        return E_INTERN;
    }

    //init instruction list
    instr_list_init(&instruction_list);

    //call parser
    ret = parse();
    if (ret != E_OK) {
#ifdef DEBUG
        fprintf(stderr, "PARSE ERROR %d\n", ret);
#endif
        instr_list_dispose(&instruction_list);
        stringFree(&token.attr.lit_string_or_id);
        table_destroy(symbol_table);
        close_File();
        return ret;
    }
#ifdef DEBUG
    fprintf(stderr, "PARSE OK\n");
#endif
    
    //call interpreter
    ret = interpret();
    if (ret != E_OK) {
#ifdef DEBUG
        fprintf(stderr, "INTERPRET ERROR %d\n", ret);
#endif
    } else {
#ifdef DEBUG
        fprintf(stderr, "INTERPRET OK\n");
#endif
    }
    
    instr_list_dispose(&instruction_list);
    stringFree(&token.attr.lit_string_or_id);
    table_destroy(symbol_table);
    close_File();
    return ret;
}
Esempio n. 2
0
File: parser.cpp Progetto: wfwt/jszb
static Stmt *parseStmt(Parser *p)
{
	String id;
	
	assert(p->tok == TK_ID);
	if (stringInit(&id, p->toklen))
		return 0;
	stringAdd(&id, p->tokval, p->toklen);
	
	p->tok = lexerGetToken(p->lex, &p->tokval, &p->toklen);
	if (p->tok == TK_COLON_EQ || p->tok == TK_COLON) {
		enum Token op = p->tok;
		p->tok = lexerGetToken(p->lex, &p->tokval, &p->toklen);
		Node *expr = parseExpr(p);
		if (expr) {
			if (p->tok == TK_SEMICOLON) {
#ifdef LOG_PARSE
				info("解析得到stmt\n");
#endif
				return stmtNew(&id, op, expr);
			} else {
				handleParserError(p, 0, "解析stmt,缺少;");
			}
		}
	} else {
		handleParserError(p, 1, "解析stmt,不识别符号,只能是:=或者:");
	}
	
	stringFree(&id);
	return 0;
}
Esempio n. 3
0
File: parser.cpp Progetto: wfwt/jszb
static void idExprClean(Node *node)
{
	IdExpr *e = (IdExpr *)node;
#ifdef LOG_CLEAN
	info("idExprClean\n");
#endif
	stringFree(&e->val);
}
Esempio n. 4
0
File: parser.cpp Progetto: wfwt/jszb
static void funcCallClean(Node *node)
{
	FuncCall *e = (FuncCall *)node;
#ifdef LOG_CLEAN
	info("funcCallClean\n");
#endif
	stringFree(&e->id);
	nodeFree((Node *)e->args);
}
Esempio n. 5
0
File: parser.cpp Progetto: wfwt/jszb
static void stmtClean(Node *node)
{
	Stmt *st = (Stmt *)node;
#ifdef LOG_CLEAN
	info("stmtClean\n");
#endif
	stringFree(&st->id);
	if (st->expr) {
		nodeFree((Node *)st->expr);
	}
}
Esempio n. 6
0
/*
** Auxiliary SQL function to recursively evaluate SQL.
*/
static void evalFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  const char *zSql = (const char*)sqlite3_value_text(argv[0]);
  String res;
  char *zErrMsg = 0;
  int rc;
  UNUSED_PARAMETER(argc);
  memset(&res, 0, sizeof(res));
  rc = sqlite3_exec(db, zSql, evalCallback, &res, &zErrMsg);
  if( zErrMsg ){
    sqlite3_result_error(context, zErrMsg, -1);
    sqlite3_free(zErrMsg);
  }else if( rc ){
    sqlite3_result_error_code(context, rc);
  }else{
    sqlite3_result_text(context, res.z, -1, SQLITE_TRANSIENT);
  }
  stringFree(&res);
}
Esempio n. 7
0
int main(int argc, char *argv[])
{
    
    pANTLR3_UINT8 filename;
    pANTLR3_INPUT_STREAM input=NULL;
    pProtoJSLexer lxr;
    pANTLR3_COMMON_TOKEN_STREAM tstream;
    pProtoJSParser psr;
    ProtoJSParser_protocol_return     pbjAST;
    if (argc < 2 || argv[1] == NULL)
        filename = (pANTLR3_UINT8)"./input";
    else
        filename = (pANTLR3_UINT8)argv[1];
    const char * outputFilename="output";
    if (argc>=3) {
        outputFilename=argv[2];
    }
    char * csOut=NULL;
    char * cppOut=NULL;
    char * cppInclude=NULL;
    int argindex;
    const char *outputInternalNamespace="_ProtoJS_Internal";
    const char *outputExternalNamespace="";
    for (argindex=3;argindex<argc;++argindex) {
        
        if (strncmp(argv[argindex],"--cpp=",6)==0) {
            cppOut=argv[argindex]+6;
        }
        if (strncmp(argv[argindex],"--cs=",5)==0) {
            csOut=argv[argindex]+5;
        }
        if (strncmp(argv[argindex],"--include=",10)==0) {
            cppInclude=argv[argindex]+10;
        }
        if (strncmp(argv[argindex],"--inamespace=",13)==0) {
            outputInternalNamespace=argv[argindex]+13;
        }
        if (strncmp(argv[argindex],"--namespace=",12)==0) {
            outputExternalNamespace=argv[argindex]+12;
        }
    }
    char*package=parsePackage((const char*)filename,outputFilename,outputInternalNamespace,outputExternalNamespace);
    pANTLR3_HASH_TABLE qualifiedTypes=antlr3HashTableNew(11);
    parseTypes((const char*)filename,outputFilename,outputInternalNamespace,outputExternalNamespace,package,qualifiedTypes);
    if(generateASTProto((const char*)filename,outputFilename,outputInternalNamespace,outputExternalNamespace,package,qualifiedTypes,&pbjAST,&lxr,&psr,&tstream,&input)) {
        pANTLR3_COMMON_TREE_NODE_STREAM    nodes;
        nodes   = antlr3CommonTreeNodeStreamNewTree(pbjAST.tree, ANTLR3_SIZE_HINT); // sIZE HINT WILL SOON BE DEPRECATED!!
        pANTLR3_STRING s = nodes->stringFactory->newRaw(nodes->stringFactory);
        grammarToString(nodes->tnstream,nodes->root,NULL,s);
        FILE*fp=fopen(outputFilename,"w");
        if (!fp) {
            perror("Unable to open output file!");
            exit(2);
        }
        if (s->size>1)
            fwrite(s->chars,s->size-1,1,fp);
        fclose(fp);
        stringFree(s);
        nodes   ->free  (nodes);        nodes   = NULL;
    }
    psr->free(psr);
    psr = NULL;
    
    tstream->free(tstream);
    tstream = NULL;
    
    
    lxr->free(lxr);
    lxr = NULL;
    input->close(input);
    input = NULL;
    return 0;
}
Esempio n. 8
0
/*
** Run a script.
*/
static void runScript(
  int iClient,       /* The client number, or 0 for the master */
  int taskId,        /* The task ID for clients.  0 for master */
  char *zScript,     /* Text of the script */
  char *zFilename    /* File from which script was read. */
){
  int lineno = 1;
  int prevLine = 1;
  int ii = 0;
  int iBegin = 0;
  int n, c, j;
  int len;
  int nArg;
  String sResult;
  char zCmd[30];
  char zError[1000];
  char azArg[MX_ARG][100];

  memset(&sResult, 0, sizeof(sResult));
  stringReset(&sResult);
  while( (c = zScript[ii])!=0 ){
    prevLine = lineno;
    len = tokenLength(zScript+ii, &lineno);
    if( isspace(c) || (c=='/' && zScript[ii+1]=='*') ){
      ii += len;
      continue;
    }
    if( c!='-' || zScript[ii+1]!='-' || !isalpha(zScript[ii+2]) ){
      ii += len;
      continue;
    }

    /* Run any prior SQL before processing the new --command */
    if( ii>iBegin ){
      char *zSql = sqlite3_mprintf("%.*s", ii-iBegin, zScript+iBegin);
      evalSql(&sResult, zSql);
      sqlite3_free(zSql);
      iBegin = ii + len;
    }

    /* Parse the --command */
    if( g.iTrace>=2 ) logMessage("%.*s", len, zScript+ii);
    n = extractToken(zScript+ii+2, len-2, zCmd, sizeof(zCmd));
    for(nArg=0; n<len-2 && nArg<MX_ARG; nArg++){
      while( n<len-2 && isspace(zScript[ii+2+n]) ){ n++; }
      if( n>=len-2 ) break;
      n += extractToken(zScript+ii+2+n, len-2-n,
                        azArg[nArg], sizeof(azArg[nArg]));
    }
    for(j=nArg; j<MX_ARG; j++) azArg[j++][0] = 0;

    /*
    **  --sleep N
    **
    ** Pause for N milliseconds
    */
    if( strcmp(zCmd, "sleep")==0 ){
      sqlite3_sleep(atoi(azArg[0]));
    }else 

    /*
    **   --exit N
    **
    ** Exit this process.  If N>0 then exit without shutting down
    ** SQLite.  (In other words, simulate a crash.)
    */
    if( strcmp(zCmd, "exit")==0 ){
      int rc = atoi(azArg[0]);
      finishScript(iClient, taskId, 1);
      if( rc==0 ) sqlite3_close(g.db);
      exit(rc);
    }else

    /*
    **   --testcase NAME
    **
    ** Begin a new test case.  Announce in the log that the test case
    ** has begun.
    */
    if( strcmp(zCmd, "testcase")==0 ){
      if( g.iTrace==1 ) logMessage("%.*s", len - 1, zScript+ii);
      stringReset(&sResult);
    }else

    /*
    **   --finish
    **
    ** Mark the current task as having finished, even if it is not.
    ** This can be used in conjunction with --exit to simulate a crash.
    */
    if( strcmp(zCmd, "finish")==0 && iClient>0 ){
      finishScript(iClient, taskId, 1);
    }else

    /*
    **  --reset
    **
    ** Reset accumulated results back to an empty string
    */
    if( strcmp(zCmd, "reset")==0 ){
      stringReset(&sResult);
    }else

    /*
    **  --match ANSWER...
    **
    ** Check to see if output matches ANSWER.  Report an error if not.
    */
    if( strcmp(zCmd, "match")==0 ){
      int jj;
      char *zAns = zScript+ii;
      for(jj=7; jj<len-1 && isspace(zAns[jj]); jj++){}
      zAns += jj;
      if( len-jj-1!=sResult.n || strncmp(sResult.z, zAns, len-jj-1) ){
        errorMessage("line %d of %s:\nExpected [%.*s]\n     Got [%s]",
          prevLine, zFilename, len-jj-1, zAns, sResult.z);
      }
      g.nTest++;
      stringReset(&sResult);
    }else

    /*
    **  --glob ANSWER...
    **  --notglob ANSWER....
    **
    ** Check to see if output does or does not match the glob pattern
    ** ANSWER.
    */
    if( strcmp(zCmd, "glob")==0 || strcmp(zCmd, "notglob")==0 ){
      int jj;
      char *zAns = zScript+ii;
      char *zCopy;
      int isGlob = (zCmd[0]=='g');
      for(jj=9-3*isGlob; jj<len-1 && isspace(zAns[jj]); jj++){}
      zAns += jj;
      zCopy = sqlite3_mprintf("%.*s", len-jj-1, zAns);
      if( (sqlite3_strglob(zCopy, sResult.z)==0)^isGlob ){
        errorMessage("line %d of %s:\nExpected [%s]\n     Got [%s]",
          prevLine, zFilename, zCopy, sResult.z);
      }
      sqlite3_free(zCopy);
      g.nTest++;
      stringReset(&sResult);
    }else

    /*
    **  --output
    **
    ** Output the result of the previous SQL.
    */
    if( strcmp(zCmd, "output")==0 ){
      logMessage("%s", sResult.z);
    }else

    /*
    **  --source FILENAME
    **
    ** Run a subscript from a separate file.
    */
    if( strcmp(zCmd, "source")==0 ){
      char *zNewFile, *zNewScript;
      char *zToDel = 0;
      zNewFile = azArg[0];
      if( zNewFile[0]!='/' ){
        int k;
        for(k=(int)strlen(zFilename)-1; k>=0 && zFilename[k]!='/'; k--){}
        if( k>0 ){
          zNewFile = zToDel = sqlite3_mprintf("%.*s/%s", k,zFilename,zNewFile);
        }
      }
      zNewScript = readFile(zNewFile);
      if( g.iTrace ) logMessage("begin script [%s]\n", zNewFile);
      runScript(0, 0, zNewScript, zNewFile);
      sqlite3_free(zNewScript);
      if( g.iTrace ) logMessage("end script [%s]\n", zNewFile);
      sqlite3_free(zToDel);
    }else

    /*
    **  --print MESSAGE....
    **
    ** Output the remainder of the line to the log file
    */
    if( strcmp(zCmd, "print")==0 ){
      int jj;
      for(jj=7; jj<len && isspace(zScript[ii+jj]); jj++){}
      logMessage("%.*s", len-jj, zScript+ii+jj);
    }else

    /*
    **  --if EXPR
    **
    ** Skip forward to the next matching --endif or --else if EXPR is false.
    */
    if( strcmp(zCmd, "if")==0 ){
      int jj, rc;
      sqlite3_stmt *pStmt;
      for(jj=4; jj<len && isspace(zScript[ii+jj]); jj++){}
      pStmt = prepareSql("SELECT %.*s", len-jj, zScript+ii+jj);
      rc = sqlite3_step(pStmt);
      if( rc!=SQLITE_ROW || sqlite3_column_int(pStmt, 0)==0 ){
        ii += findEndif(zScript+ii+len, 1, &lineno);
      }
      sqlite3_finalize(pStmt);
    }else

    /*
    **  --else
    **
    ** This command can only be encountered if currently inside an --if that
    ** is true.  Skip forward to the next matching --endif.
    */
    if( strcmp(zCmd, "else")==0 ){
      ii += findEndif(zScript+ii+len, 0, &lineno);
    }else

    /*
    **  --endif
    **
    ** This command can only be encountered if currently inside an --if that
    ** is true or an --else of a false if.  This is a no-op.
    */
    if( strcmp(zCmd, "endif")==0 ){
      /* no-op */
    }else

    /*
    **  --start CLIENT
    **
    ** Start up the given client.
    */
    if( strcmp(zCmd, "start")==0 && iClient==0 ){
      int iNewClient = atoi(azArg[0]);
      if( iNewClient>0 ){
        startClient(iNewClient);
      }
    }else

    /*
    **  --wait CLIENT TIMEOUT
    **
    ** Wait until all tasks complete for the given client.  If CLIENT is
    ** "all" then wait for all clients to complete.  Wait no longer than
    ** TIMEOUT milliseconds (default 10,000)
    */
    if( strcmp(zCmd, "wait")==0 && iClient==0 ){
      int iTimeout = nArg>=2 ? atoi(azArg[1]) : 10000;
      sqlite3_snprintf(sizeof(zError),zError,"line %d of %s\n",
                       prevLine, zFilename);
      waitForClient(atoi(azArg[0]), iTimeout, zError);
    }else

    /*
    **  --task CLIENT
    **     <task-content-here>
    **  --end
    **
    ** Assign work to a client.  Start the client if it is not running
    ** already.
    */
    if( strcmp(zCmd, "task")==0 && iClient==0 ){
      int iTarget = atoi(azArg[0]);
      int iEnd;
      char *zTask;
      char *zTName;
      iEnd = findEnd(zScript+ii+len, &lineno);
      if( iTarget<0 ){
        errorMessage("line %d of %s: bad client number: %d",
                     prevLine, zFilename, iTarget);
      }else{
        zTask = sqlite3_mprintf("%.*s", iEnd, zScript+ii+len);
        if( nArg>1 ){
          zTName = sqlite3_mprintf("%s", azArg[1]);
        }else{
          zTName = sqlite3_mprintf("%s:%d", filenameTail(zFilename), prevLine);
        }
        startClient(iTarget);
        runSql("INSERT INTO task(client,script,name)"
               " VALUES(%d,'%q',%Q)", iTarget, zTask, zTName);
        sqlite3_free(zTask);
        sqlite3_free(zTName);
      }
      iEnd += tokenLength(zScript+ii+len+iEnd, &lineno);
      len += iEnd;
      iBegin = ii+len;
    }else

    /*
    **  --breakpoint
    **
    ** This command calls "test_breakpoint()" which is a routine provided
    ** as a convenient place to set a debugger breakpoint.
    */
    if( strcmp(zCmd, "breakpoint")==0 ){
      test_breakpoint();
    }else

    /*
    **  --show-sql-errors BOOLEAN
    **
    ** Turn display of SQL errors on and off.
    */
    if( strcmp(zCmd, "show-sql-errors")==0 ){
      g.bIgnoreSqlErrors = nArg>=1 ? !booleanValue(azArg[0]) : 1;
    }else


    /* error */{
      errorMessage("line %d of %s: unknown command --%s",
                   prevLine, zFilename, zCmd);
    }
    ii += len;
  }
  if( iBegin<ii ){
    char *zSql = sqlite3_mprintf("%.*s", ii-iBegin, zScript+iBegin);
    runSql(zSql);
    sqlite3_free(zSql);
  }
  stringFree(&sResult);
}
Esempio n. 9
0
int main(void)
{
    t_table *table = table_init(128);
    if (table == NULL) {
        fprintf(stderr, "Table could not be initialized!\n");
        return EXIT_FAILURE;
    }
    
    print_table_info(table);
    print_table(table);

    int data_pole[NUM] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    t_string key_pole[NUM];

    int i;
    for (i = 0; i < NUM; i++) {
        stringInit(&key_pole[i]);
    }

    for (i = 0; i < NUM; i++) {
        stringAddChar(&key_pole[i], 'a' + i);
    }

    int ret = 0;
    t_tab_data * data_ptr;

    for (i = 0; i < NUM; i++) {
        ret = table_insert(table, &key_pole[i], &data_ptr);
        switch (ret) {
        case TAB_INSERT_OK:
            data_ptr->a = data_pole[i];
            break;
        case TAB_INSERT_FOUND:
            fprintf(stderr, "Item already inserted\n");
            break;
        case TAB_INSERT_ALL_ERR:
            fprintf(stderr, "Allocation error\n");
            break;
        }
    }

    print_table_info(table);
    print_table(table);
    
    /*
    //1. raz
    printf("INSERT\n\n");
    for (i = 0; i < NUM; i++) {
        ret = table_insert(table, key_pole[i], 7, (t_tab_data **) &data);
        switch (ret) {
        case TAB_INSERT_FAIL:
            fprintf(stderr, "Item already inserted.\n");
            break;
        case TAB_INSERT_FULL:
            while (ret == TAB_INSERT_FULL) {
                if (table_resize(table) == TAB_RESIZE_FAIL) {
                    fprintf(stderr, "RESIZE FAIL\n");
                    table_destroy(table);
                    return EXIT_FAILURE;
                }
                ret = table_insert(table, key_pole[i], 7, (t_tab_data **)&data);
            }
            if (ret == TAB_INSERT_FAIL) {
                fprintf(stderr, "Item already inserted.\n");
                break;
            }
            if (ret == TAB_INSERT_ALL_ERR) {
                fprintf(stderr, "ALLOC ERR\n");
                table_destroy(table);
                return EXIT_FAILURE;
            }
            *(int *)data = data_pole[i];
            break;
        case TAB_INSERT_OK:
            *(int *)data = data_pole[i];
            break;
        case TAB_INSERT_ALL_ERR:
            fprintf(stderr, "ALLOC ERROR\n");
            table_destroy(table);
            return EXIT_FAILURE;
        }
    }

    print_table(table);
    */
    
    printf("-----------------------------------------------------------------------------------------\n\n");

    printf("GET DATA\n\n");
    for (i = 0; i < NUM; i++) {
        ret = table_search(table, &key_pole[i], (t_tab_data **) &data_ptr);
        if (ret == TAB_SEARCH_OK) {
            printf("Key:    %s\n", key_pole[i].string);
            printf("Data:  %d\n\n", data_ptr == NULL ? -1 : ((t_tab_data *)data_ptr)->a);
        }
    }

    /*
    print_table(table);
    */

    for (i = 0; i < NUM; i++) {
        stringFree(&key_pole[i]);
    }
    table_destroy(table);
    return EXIT_SUCCESS;
}
/****************************************************************************
* Menu option #6: Delete Stop Words
* Removes common words from the index supplied from an external file.
****************************************************************************/
void deleteStopWords(IndexType* index)
{
  FILE *fp;
  unsigned int injunk,in,notin;
  char word[MAXLENGTH],c;
  char buffer[BUFFSIZE];
  WordTypePtr node,prev,temp;
  String line;

  printf("\nDelete Stop Words\n");
  printf("-----------------\n");


  getString(word,MAXLENGTH,0,"Enter name of stop word file:");

  if(strlen(word)==0)
  {
    printf("Delete Stop Words cancelled. Returning to main menu.\n");
    return;
  }

  if((fp=fopen(word,"rb"))==NULL)
  {
    printf("Failed to read %s !\n",word);
    return;
  }

  setvbuf(fp,buffer,_IOFBF,BUFFSIZE);

  stringInit(&line);
  injunk=FALSE;
  in=FALSE;
  notin=FALSE;

  while((c=fgetc(fp))!=EOF)
  {
    if((c>=a && c<=z) || (c>=A && c<=Z))
    {
      injunk=FALSE;
      stringAddChar(&line,c);
    }
    if(!injunk)
    {
      if(c==SPACE || c=='\n')
      {
        /*found the word so search index and remove the node if its found*/
        node=index->headWord;
        prev=node;
        while(node!=NULL)
        {
          /*found the word to delete so delete it*/
          if(strcmp(node->word,line.contents)==0)
          {
            temp=deletebetween(prev,node);

            /*temp=node;*/


            if(node==index->headWord)
                index->headWord=temp;
            else
                node=temp;


            stringClear(&line);
            injunk=TRUE;
            in++;
            break;
          }
          prev=node;
          node=node->nextWord;

        }
        /*the word wasnt found in the list*/
        if(node==NULL)
            notin++;

      }
    }
  }
  printf("\n\n%d words removed from the index. %d words not found."
         ,in,notin);

  stringFree(&line);
  fclose(fp);


}
/****************************************************************************
* Menu option #4: Stemming Report
* Creates an external file with statistics of all words in the index that
* have common suffixes.
****************************************************************************/
void stemmingReport(IndexType* index)
{
  FILE *fp;
  WordTypePtr node;
  char filename[FILENAME_MAX];
  String stem;
  char c;
  char buffer[BUFFSIZE];
  char* longestword;

  unsigned int nodelength;



  printf("\nStemming Report\n");
  printf("---------------\n");


  getString(filename,FILENAME_MAX,0,"Enter name of a suffixes file:");
  /*if they enter no file name cancel to the main menu*/
  if(strlen(filename)==0)
  {
    printf("\nStemm report cancelled. Returning to main menu.\n");
    return;
  }

  /*open the file*/
  fp=fopen(filename,"r");
  if(fp==NULL)
  {
    printf("\n Failed to read %s file!\n",filename);
    return;
  }

   stringInit(&stem);

  /*reserve space for longest word*/
  longestword=malloc(strlen(index->longestWord->word)*sizeof(char));


  /*speed up*/
  setvbuf(fp,buffer,_IOFBF,BUFFSIZE);

  printf("\nResults:\n\n");

  /*loop through all nodes*/
  node=index->headWord;
  while(node!=NULL)
  {
    /*printf("node is %s\n",node->word);*/
    nodelength=strlen(node->word);

    /*loop through all stem words*/
    fseek(fp,0,0);
    while((c=fgetc(fp))!=EOF)
    {
      /*next stem words is ready*/
      if(c=='\n')
      {
        /*if the stem word is larger than the node word skip the node*/
        if(stem.offset>nodelength)
        {
          stringClear(&stem);
          continue;
        }
        /*check if the node word containts the stem word*/
        if(strcmp(stem.contents,node->word+nodelength-stem.offset)==0)
        {
          /*get the base word and null terminate*/
          strncpy(longestword,node->word,nodelength-stem.offset);
          *(longestword+nodelength-stem.offset)='\0';
          /*display the node and the stem prefix*/
          printf("%s %s\n",node->word,longestword);
        }
        stringClear(&stem);
      }
      /*keep building the stem word*/
      else
        stringAddChar(&stem,c);
    }
    node=node->nextWord;
  }
  fclose(fp);
  free(longestword);
  stringFree(&stem);
}