windows-nt/Source/XPSP1/NT/base/ntsetup/mpk/misclib/msgfile.c

269 lines
5.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
msgfile.c
Abstract:
Routines to load and process a text message file.
The message file is in the following format:
[<id>]
text
[<id>]
text
etc.
Notes:
1) Lines in the file before the first section are ignored. This is the
only mechanism for comments in the file.
2) To be recognized as a section name, the [ must be the first
character on the line, and there cannot be any spaces between
the [ and the ]. The number must be a decimal number in the range
0 - 65535 inclusive.
3) Trailing space at the end of a line is ignored.
4) Empty lines at the trail end of a message are ignored completely.
Empty means a newline only or whitespace and a newline only.
5) The final newline in a message is ignored but internal ones
are kept. Thus in the following example, message #3 is the 4 line
message "\nThis\nis\n\na\n\nmessage"
[3]
This
is
a
message
[4]
Author:
Ted Miller (tedm) 20 June 1997
Revision History:
--*/
#include <mytypes.h>
#include <msgfile.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define MAX_LINE_LEN 100
#define MAX_MSG_LEN 5000
BOOL
PatchMessagesFromFile(
IN FPCHAR Filename,
IN OUT FPMESSAGE_STRING Messages,
IN UINT MessageCount
);
BOOL
ProcessMessage(
IN char *msg,
IN UINT MsgNumber,
IN FPMESSAGE_STRING Messages,
IN UINT MessageCount
);
BOOL
GetTextForProgram(
IN FPCHAR Argv0,
IN OUT FPMESSAGE_STRING Messages,
IN UINT MessageCount
)
{
char Filename[256];
char *p;
strcpy(Filename,Argv0);
if(p = strrchr(Filename,'\\')) {
p++;
} else {
p = Filename;
}
if(p = strchr(p,'.')) {
*p = 0;
}
strcat(p,".msg");
return(PatchMessagesFromFile(Filename,Messages,MessageCount));
}
BOOL
PatchMessagesFromFile(
IN FPCHAR Filename,
IN OUT FPMESSAGE_STRING Messages,
IN UINT MessageCount
)
{
FILE *hFile;
char line[MAX_LINE_LEN];
char *msg;
char *End;
UINT MsgNumber;
unsigned long l;
unsigned u;
BOOL Valid;
msg = malloc(MAX_MSG_LEN);
if(!msg) {
return(FALSE);
}
//
// Open the file.
//
hFile = fopen(Filename,"rt");
if(!hFile) {
free(msg);
return(FALSE);
}
MsgNumber = (UINT)(-1);
Valid = TRUE;
while(Valid && fgets(line,MAX_LINE_LEN,hFile)) {
if(line[0] == '[') {
//
// New message. Terminate the current one and then make sure
// the section name specifies a valid number.
//
if(MsgNumber != (UINT)(-1)) {
Valid = ProcessMessage(msg,MsgNumber,Messages,MessageCount);
}
if(Valid) {
l = strtoul(&line[1],&End,10);
if((l > 65535L) || (*End != ']')) {
Valid = FALSE;
} else {
MsgNumber = (UINT)l;
msg[0] = 0;
}
}
} else {
//
// Ignore lines in the file before the first section
//
if(MsgNumber != (UINT)(-1)) {
//
// Strip out trailing space. Account for the newline that
// fgets leaves in the buffer.
//
u = strlen(line);
while(u && ((line[u-1] == ' ') || (line[u-1] == '\t') || (line[u-1] == '\n'))) {
u--;
}
//
// Put a newline back at the end of the line.
//
line[u++] = '\n';
line[u] = 0;
if((strlen(msg) + u) < MAX_MSG_LEN) {
strcat(msg,line);
}
}
}
}
//
// Check loop termination condition to see whether we read the whole
// file correctly.
//
if(Valid && ferror(hFile)) {
Valid = FALSE;
}
fclose(hFile);
//
// Process pending messsage if there is one.
//
if(Valid && (MsgNumber != (UINT)(-1))) {
if(!ProcessMessage(msg,MsgNumber,Messages,MessageCount)) {
Valid = FALSE;
}
}
free(msg);
return(Valid);
}
BOOL
ProcessMessage(
IN char *msg,
IN UINT MsgNumber,
IN FPMESSAGE_STRING Messages,
IN UINT MessageCount
)
{
UINT m;
unsigned u;
FPVOID p;
//
// Strip out trailing newline(s).
//
u = strlen(msg);
while(u && (msg[u-1] == '\n')) {
msg[--u] = 0;
}
//
// Locate the relevent message in the caller's table.
//
for(m=0; m<MessageCount; m++) {
if(Messages[m].Id == MsgNumber) {
//
// If the message fits in place, put it there.
// Otherwise allocate memory and copy it.
//
if(!(*Messages[m].String) || (u > strlen(*Messages[m].String))) {
p = malloc(u+1);
if(!p) {
return(FALSE);
}
if(*Messages[m].String) {
free(*Messages[m].String);
}
*Messages[m].String = p;
}
strcpy(*Messages[m].String,msg);
break;
}
}
return(TRUE);
}