/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* HISTORY
*/
#ifdef REV_INFO
#ifndef lint
static char *rcsid = "$XConsortium: io.c /main/6 1995/07/14 09:46:23 drk $";
#endif
#endif
#include <stdlib.h>
#include <unistd.h>
#include <Xm/Xm.h>
#include <Xm/MessageB.h>
#include <Xm/Notebook.h>
#include <Xm/Text.h>
#include <Exm/TabB.h>
#include <stdio.h>
#include "page.h"
Widget ioerror = (Widget) NULL;
extern Widget notebook, textw, shell;
Page pages[MAXPAGES];
extern int currentPage;
extern int modified;
int maxpages;
Page AllocPage();
/* Pages are stored pretty simply:
* each page starts with "*PLabel"
* the next line has "*TLabel" if there is a major tab
* or with *MLabel for a minor tab
* *Cnnnn has the cursor position
* *Lnnnn has the top line position
* the page's text continues to the next page start.
* regular lines start with .
*/
void ParseNewLines(label)
char * label ;
{
/* look for "\n" and change in '\n' and compact */
char * s ;
while (*label) {
if ((*label == '\\') && (*(label+1) == 'n')) {
*label = '\n' ;
s = label+1 ;
while (*s) {
*s = *(s+1) ;
s++ ;
}
}
label ++ ;
}
}
static void PrintWithNewLines(output, label)
FILE *output ;
char * label ;
{
/* look for '\n' and print "\n" */
while (*label) {
if (*label == '\n') {
fprintf(output,"\\n");
} else
fprintf(output,"%c", *label);
label ++ ;
}
fprintf(output,"\n"); label ++ ;
}
void
ReadDB(char* filename)
{
FILE *input;
int i, number, first = 1;
char *buffer;
int max, current;
char line[1024];
Arg args[5];
Widget tab;
input = fopen(filename, "r");
if (ioerror == (Widget) NULL) {
ioerror = XmCreateInformationDialog(shell, "IO_Error_Dialog", NULL, 0);
}
if (input == NULL && strncmp(filename,"untitled",8) != 0) {
XmString str;
char buf[256];
sprintf(buf, "Can't access (%s) for reading", filename);
str = XmStringCreateLocalized(buf);
XtVaSetValues(ioerror, XmNmessageString, str, NULL, NULL);
XtManageChild(ioerror);
}
/* Destroy current pages on reread */
for(i = 0; i < maxpages; i++) {
XtFree(pages[i] -> page);
XtFree(pages[i] -> majorTab);
XtFree(pages[i] -> minorTab);
XtFree(pages[i] -> label);
if (pages[i] -> majorPB)
XtDestroyWidget(pages[i] -> majorPB);
if (pages[i] -> minorPB)
XtDestroyWidget(pages[i] -> minorPB);
}
number = 0;
if (input != NULL) {
max = MAXINIT;
buffer = (char*) XtMalloc(max);
buffer[0] = 0; /* Reset page buffer */
current = 0;
pages[0] = AllocPage();
while(fgets(line, 1024, input) != NULL) {
if (line[0] == '*') /* Special */
{
if (line[1] == 'P') /* New Page */
{
if (first == 1) {
first = 0;
}
else {
pages[number] -> page = buffer;
current = 0;
max = MAXINIT;
buffer = (char*) XtMalloc(max);
buffer[0] = 0; /* Reset page buffer */
number++;
pages[number] = AllocPage();
}
if (strlen(line) > 3) {
line[strlen(line) - 1] = 0; /* Remove newline */
pages[number] -> label = XtNewString(&line[2]);
}
}
else if (line[1] == 'T') /* Tab */
{
XmString name;
line[strlen(line) - 1] = 0; /* Remove newline */
if (strlen(line) > 3) {
pages[number] -> majorTab = XtNewString(&line[2]);
i = 0;
ParseNewLines(pages[number] -> majorTab);
name = XmStringGenerate(pages[number] -> majorTab, NULL,
XmCHARSET_TEXT, NULL);
XtSetArg(args[i], XmNnotebookChildType, XmMAJOR_TAB); i++;
XtSetArg(args[i], XmNpageNumber, (number + 1)); i++;
XtSetArg(args[i], ExmNcompoundString, name); i++;
XtSetArg(args[i], XmNshadowThickness, 1); i++;
tab = ExmCreateTabButton(notebook, "atab", args, i);
XtManageChild(tab);
pages[number] -> majorPB = tab;
XmStringFree(name);
}
}
else if (line[1] == 'M') /* Minor Tab */
{
XmString name;
line[strlen(line) - 1] = 0; /* Remove newline */
if (strlen(line) > 3) {
pages[number] -> minorTab = XtNewString(&line[2]);
i = 0;
ParseNewLines(pages[number] -> minorTab);
name = XmStringGenerate(pages[number] -> minorTab, NULL,
XmCHARSET_TEXT, NULL);
XtSetArg(args[i], XmNnotebookChildType, XmMINOR_TAB); i++;
XtSetArg(args[i], XmNpageNumber, (number + 1)); i++;
XtSetArg(args[i], ExmNcompoundString, name); i++;
XtSetArg(args[i], XmNshadowThickness, 1); i++;
tab = ExmCreateTabButton(notebook, "atab", args, i);
pages[number] -> minorPB = tab;
XtManageChild(tab);
XmStringFree(name);
}
}
else if (line[1] == 'C') /* Cursor position */
{
pages[number] -> lastcursorpos = strtol(&line[2], NULL, 0);
}
else if (line[1] == 'L') /* Top line position */
{
pages[number] -> lasttoppos = strtol(&line[2], NULL, 0);
}
}
else /* Regular line. "Remove" . and append */
{
current += strlen(&line[1]);
if ((current - 2) > max) {
max = 2 * max;
buffer=(char*) XtRealloc(buffer, max);
}
strcat(buffer, &line[1]);
}
}
}
/* If we didn't have a file to read, we need to setup a page */
if (input == NULL) {
number = 0;
pages[0] = AllocPage();
pages[0] -> page = XtMalloc(2);
pages[0] -> page[0] = 0;
} else {
pages[number] -> page = buffer;
}
maxpages = number;
i = 0;
XtSetArg(args[i], XmNlastPageNumber, maxpages + 1); i++;
XtSetArg(args[i], XmNcurrentPageNumber, 1); i++;
XtSetValues(notebook, args, i);
if (input) fclose(input);
}
void
SaveDB(char* filename)
{
int number;
FILE *output;
int i;
char oldfilename[256];
if (ioerror == (Widget) NULL) {
ioerror = XmCreateInformationDialog(shell, "IO_Error_Dialog", NULL, 0);
}
if (access(filename, F_OK) == 0 &&
access(filename, W_OK) != 0) {
XmString str;
char buf[256];
sprintf(buf, "Can't access (%s) for writing", filename);
str = XmStringCreateLocalized(buf);
XtVaSetValues(ioerror, XmNmessageString, str, NULL, NULL);
XtManageChild(ioerror);
return;
}
/* Append a ~ to make the old filename */
if (access(filename, F_OK) == 0) {
strcpy(oldfilename, filename);
strcat(oldfilename, "~");
rename(filename, oldfilename);
}
/* Make sure to grab current page */
if (modified) {
if (pages[currentPage] -> page != NULL)
XtFree(pages[currentPage] -> page);
pages[currentPage] -> page = XmTextGetString(textw);
}
output = fopen(filename, "w");
for(number = 0; number <= maxpages; number++) {
if (pages[number] -> label != NULL)
fprintf(output, "*P%s\n", pages[number] -> label);
else
fprintf(output, "*P\n");
if (pages[number] -> majorTab != NULL) {
fprintf(output, "*T");
PrintWithNewLines(output, pages[number] -> majorTab);
}
if (pages[number] -> minorTab != NULL) {
fprintf(output, "*M");
PrintWithNewLines(output, pages[number] -> minorTab);
}
fprintf(output, "*C%d\n", pages[number] -> lastcursorpos);
fprintf(output, "*L%d\n", pages[number] -> lasttoppos);
fputc('.', output);
if (pages[number] -> page != NULL) {
for(i = 0; pages[number] -> page[i] != 0; i++) {
fputc(pages[number] -> page[i], output);
if (pages[number] -> page[i] == '\n')
fputc('.', output);
}
}
fputc('\n', output);
}
fclose(output);
}
Page AllocPage()
{
Page p;
p = (Page) XtMalloc(sizeof(PageRec));
p -> page = NULL;
p -> label = NULL;
p -> minorTab = NULL;
p -> majorTab = NULL;
p -> minorPB = (Widget) 0;
p -> majorPB = (Widget) 0;
p -> lasttoppos = 0;
p -> lastcursorpos = 0;
return(p);
}