There are a few other things that might trip you up..
If FReadLine errors, it will return a negative value, which is not NULL.
So even if FReadLine errors, you'll still process it's result as if it were a good line.
IDOS->FReadLine will terminate on a linefeed, but the linefeed is left at the end of each line.
This shows up in a listbrowser as a "box" at each line end.
In your example code, the input_file is left open.. the "IDOS->FClose()" at the end of the
example you gave will never be reached.
And as you already figured out, you need LBNCA_CopyText, TRUE before each LBNCA_Text, "" so that the
Code: Select all
;/*
;
; To compile from the Shell, simply type: 'Execute LBRFiles.c'
;
gcc -N -o LBRFiles lbrfiles.c -Wall
IF NOT WARN
LBRFiles lbrfiles.c
ENDIF
quit
*/
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include <proto/intuition.h>
#include <proto/listbrowser.h>
#include <proto/window.h>
#include <proto/layout.h>
#include <classes/window.h>
#include <string.h>
Class *WindowClass = NULL;
struct Library *WindowBase = NULL;
Class *LayoutClass = NULL;
struct Library *LayoutBase = NULL;
Class *ListBrowserClass = NULL;
struct Library *ListBrowserBase = NULL;
struct ListBrowserIFace *IListBrowser = NULL;
struct Library *IntuitionBase = NULL;
struct IntuitionIFace *IIntuition = NULL;
struct List *make_listbrowser_file (char *filepath);
BOOL openGlobals(void);
BOOL closeGlobals(CONST_STRPTR);
// Any characters in badChar will be replaced with a space.
// badChar MUST have a zero at the end!!!
char badChar[] = {'\n', '\t',0};
struct List *make_listbrowser_file (char *filepath) /// called with (input_file)
{
BPTR input_file = IDOS->FOpen(filepath, MODE_OLDFILE,0);
if(0 == input_file)
{
IDOS->Printf("Could not open file %s for reading\n", filepath);
return(NULL);
}
struct List *list = IExec->AllocSysObjectTags(ASOT_LIST, TAG_END);
if(NULL == list)
{
IDOS->Printf("Could not allocate browser list\n");
IDOS->FClose(input_file);
return(NULL);
}
struct FReadLineData *frld = IDOS->AllocDosObject(DOS_FREADLINEDATA, TAG_END);
if(NULL == frld)
{
IDOS->Printf("Could not alloc FReadLineData struct\n");
IExec->FreeSysObject(ASOT_LIST, list);
IDOS->FClose(input_file);
return(NULL);
}
int32 len, count = 0;
struct Node *node;
len = IDOS->FReadLine(input_file, frld);
while(len > 0)
{
// replace badChars with spaces
char *next;
while((next = strpbrk(frld->frld_Line, &badChar[0])))
{
*next = ' ';
}
if ((node = IListBrowser->AllocListBrowserNode (
1,
// CopyText, TRUE is required because the buffer
// contents will be changing.. so we ask the
// listbrowser to make a copy of each entry.
LBNCA_CopyText, TRUE,
LBNCA_Text, frld->frld_Line,
TAG_END )))
{
IExec->AddTail (list,node);
count++;
}
else
{
IDOS->Printf("LBNode allocation failure\n");
IDOS->SetIoErr(ERROR_NO_FREE_STORE);
len = -1;
break;
}
len = IDOS->FReadLine(input_file, frld);
}
if(len < 0)
{
IDOS->PrintFault(IDOS->IoErr(), NULL);
IListBrowser->FreeListBrowserList(list);
IExec->FreeSysObject(ASOT_LIST, list);
list = NULL;
}
IDOS->FreeDosObject(DOS_FREADLINEDATA, frld);
IDOS->FClose(input_file);
return(list);
}
int main(int argc, char **argv)
{
if(argc < 2)
{
IDOS->Printf("Required filename missing\n");
return(RETURN_FAIL);
}
if(!openGlobals())
{
return(RETURN_FAIL);
}
// make the list
struct List *file_list = make_listbrowser_file(argv[1]);
// show the list in a listbrowser window
if(file_list)
{
Object *gadget;
Object *winOb = IIntuition->NewObject(WindowClass,NULL,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_DragBar, TRUE,
WA_Title, "ListBrowser Example",
WINDOW_Position, WPOS_CENTERSCREEN,
WA_Width, 300,
WA_Height, 300,
WINDOW_Layout, IIntuition->NewObject(LayoutClass,NULL,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_AddChild, gadget = IIntuition->NewObject(
ListBrowserClass, NULL,
LISTBROWSER_Labels, file_list,
TAG_END),
TAG_END),
TAG_END);
if(winOb && (IIntuition->IDoMethod(winOb, WM_OPEN)))
{
uint32 signal, result, done = FALSE;
uint16 code;
IIntuition->GetAttr(WINDOW_SigMask, winOb, &signal);
while(!done)
{
IExec->Wait(signal);
while ( (result = IIntuition->IDoMethod(winOb, WM_HANDLEINPUT, &code) ) != WMHI_LASTMSG )
{
if(WMHI_CLOSEWINDOW == (result & WMHI_CLASSMASK))
{
done = TRUE;
}
}
}
IIntuition->DisposeObject(winOb);
}
IListBrowser->FreeListBrowserList(file_list);
IExec->FreeSysObject(ASOT_LIST, file_list);
}
closeGlobals(NULL);
return(RETURN_OK);
}
BOOL openGlobals(void)
{
if(!(IntuitionBase = IExec->OpenLibrary("intuition.library", 53)))
{
return(closeGlobals("Failed to open Intuition"));
}
if(!(IIntuition = (struct IntuitionIFace *)IExec->GetInterface(IntuitionBase, "main", 1, NULL)))
{
return(closeGlobals("Failed to get intuition interface\n"));
}
if(!(WindowBase = (struct Library *)IIntuition->OpenClass(
"classes/window.class", 53, &WindowClass)))
{
return(closeGlobals("Failed to open Window Class"));
}
if(!(LayoutBase = (struct Library *)IIntuition->OpenClass(
"gadgets/layout.gadget", 53, &LayoutClass)))
{
return(closeGlobals("Failed to open Layout Class"));
}
if(!(ListBrowserBase = (struct Library *)IIntuition->OpenClass(
"gadgets/listbrowser.gadget", 53, &ListBrowserClass)))
{
return(closeGlobals("Failed to open listbrowser class"));
}
IListBrowser = (struct ListBrowserIFace *)IExec->GetInterface(
(struct Library *)ListBrowserBase, "main", 1L, NULL);
if(NULL == IListBrowser)
{
return(closeGlobals("Failed to get ListBrowser interface"));
}
return(TRUE);
}
BOOL closeGlobals(CONST_STRPTR why)
{
if(why)
{
IDOS->Printf("%s\n", why);
}
IExec->DropInterface((struct Interface *)IListBrowser);
IIntuition->CloseClass((struct ClassLibrary *)ListBrowserBase);
IIntuition->CloseClass((struct ClassLibrary *)LayoutBase);
IIntuition->CloseClass((struct ClassLibrary *)WindowBase);
IExec->DropInterface((struct Interface *)IIntuition);
IExec->CloseLibrary(IntuitionBase);
return(FALSE);
}