/*
|
/*
|
* doschk - check filenames for DOS (and SYSV) compatibility
|
* doschk - check filenames for DOS (and SYSV) compatibility
|
*
|
*
|
* Copyright (C) 1993 DJ Delorie
|
* Copyright (C) 1993 DJ Delorie
|
*
|
*
|
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
* the Free Software Foundation; either version 2, or (at your option)
|
* the Free Software Foundation; either version 2, or (at your option)
|
* any later version.
|
* any later version.
|
*
|
*
|
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
*
|
*
|
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
* along with this program; if not, write to: The Free Software Foundation,
|
* along with this program; if not, write to: The Free Software Foundation,
|
* Inc.; 675 Mass Ave. Cambridge, MA 02139, USA.
|
* Inc.; 675 Mass Ave. Cambridge, MA 02139, USA.
|
*
|
*
|
* This program is intended as a utility to help software developers
|
* This program is intended as a utility to help software developers
|
* ensure that their source file names are distinguishable on MS-DOS and
|
* ensure that their source file names are distinguishable on MS-DOS and
|
* 14-character SYSV platforms. To perform this task, doschk reads a
|
* 14-character SYSV platforms. To perform this task, doschk reads a
|
* list of filenames and produces a report of all the conflicts that
|
* list of filenames and produces a report of all the conflicts that
|
* would arise if the files were transferred to a MS-DOS or SYSV
|
* would arise if the files were transferred to a MS-DOS or SYSV
|
* platform. It also reports any file names that would conflict with
|
* platform. It also reports any file names that would conflict with
|
* MS-DOS device names.
|
* MS-DOS device names.
|
*
|
*
|
* To use this program, you must feed it a list of filenames in this
|
* To use this program, you must feed it a list of filenames in this
|
* format:
|
* format:
|
*
|
*
|
* dir
|
* dir
|
* dir/file1.ext
|
* dir/file1.ext
|
* dir/file2.exe
|
* dir/file2.exe
|
* dir/dir2
|
* dir/dir2
|
* dir/dir2/file3.ext
|
* dir/dir2/file3.ext
|
*
|
*
|
* If the list does not include the directory-only lines (like dir/dir2)
|
* If the list does not include the directory-only lines (like dir/dir2)
|
* then their names will not be checked for uniqueness, else they will
|
* then their names will not be checked for uniqueness, else they will
|
* be. Typical uses of this program are like these:
|
* be. Typical uses of this program are like these:
|
*
|
*
|
* find . -print | doschk
|
* find . -print | doschk
|
* tar tf file.tar | doschk
|
* tar tf file.tar | doschk
|
*
|
*
|
* If this program produces no output, then all your files are MS-DOS
|
* If this program produces no output, then all your files are MS-DOS
|
* compatible. Any output messages are designed to be self-explanatory
|
* compatible. Any output messages are designed to be self-explanatory
|
* and indicate cases where the files will not transfer to MS-DOS without
|
* and indicate cases where the files will not transfer to MS-DOS without
|
* problems.
|
* problems.
|
*
|
*
|
*/
|
*/
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <ctype.h>
|
#include <ctype.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
extern char *malloc ();
|
extern char *malloc ();
|
|
|
typedef struct ENT
|
typedef struct ENT
|
{
|
{
|
struct ENT *next;
|
struct ENT *next;
|
char *dos_name;
|
char *dos_name;
|
char *full_name;
|
char *full_name;
|
char *path;
|
char *path;
|
int tagged;
|
int tagged;
|
} ENT;
|
} ENT;
|
|
|
/*
|
/*
|
* List of filenames in MSDOG that are special devices.
|
* List of filenames in MSDOG that are special devices.
|
* Not all of these are problems on all MSLOSS systems, but most would not
|
* Not all of these are problems on all MSLOSS systems, but most would not
|
* work on most of them.
|
* work on most of them.
|
*/
|
*/
|
static char *dos_special_names[] =
|
static char *dos_special_names[] =
|
{
|
{
|
"NUL",
|
"NUL",
|
"CON",
|
"CON",
|
"PRN",
|
"PRN",
|
"AUX",
|
"AUX",
|
"COM1",
|
"COM1",
|
"COM2",
|
"COM2",
|
"COM3",
|
"COM3",
|
"COM4",
|
"COM4",
|
"LPT1",
|
"LPT1",
|
"LPT2",
|
"LPT2",
|
"LPT3",
|
"LPT3",
|
"MS$MOUSE",
|
"MS$MOUSE",
|
"EMMXXXX0",
|
"EMMXXXX0",
|
"XMSXXXX0",
|
"XMSXXXX0",
|
"SMARTAAR",
|
"SMARTAAR",
|
"SETVERXX",
|
"SETVERXX",
|
NULL
|
NULL
|
} ;
|
} ;
|
|
|
ENT *eroot = 0;
|
ENT *eroot = 0;
|
|
|
int first_inv = 1;
|
int first_inv = 1;
|
int first_msg = 1;
|
int first_msg = 1;
|
|
|
/****************************************************************\
|
/****************************************************************\
|
* Utility routines *
|
* Utility routines *
|
\****************************************************************/
|
\****************************************************************/
|
|
|
void
|
void
|
invalid_msg ()
|
invalid_msg ()
|
{
|
{
|
if (first_inv)
|
if (first_inv)
|
{
|
{
|
if (first_msg)
|
if (first_msg)
|
first_msg = 0;
|
first_msg = 0;
|
else
|
else
|
putchar ('\n');
|
putchar ('\n');
|
printf ("The following files are not valid DOS file names:\n");
|
printf ("The following files are not valid DOS file names:\n");
|
first_inv = 0;
|
first_inv = 0;
|
}
|
}
|
}
|
}
|
|
|
char *
|
char *
|
xmalloc (size)
|
xmalloc (size)
|
int size;
|
int size;
|
{
|
{
|
char *s;
|
char *s;
|
|
|
if (size == 0)
|
if (size == 0)
|
return NULL;
|
return NULL;
|
|
|
s = (char *) malloc (size);
|
s = (char *) malloc (size);
|
|
|
if (s == NULL)
|
if (s == NULL)
|
{
|
{
|
fprintf (stderr, "Virtual memory exhausted.\n");
|
fprintf (stderr, "Virtual memory exhausted.\n");
|
exit (1);
|
exit (1);
|
}
|
}
|
|
|
return s;
|
return s;
|
}
|
}
|
|
|
ENT *
|
ENT *
|
alloc_ent ()
|
alloc_ent ()
|
{
|
{
|
ENT *rv = (ENT *) xmalloc (sizeof (ENT));
|
ENT *rv = (ENT *) xmalloc (sizeof (ENT));
|
memset (rv, 0, sizeof (ENT));
|
memset (rv, 0, sizeof (ENT));
|
return rv;
|
return rv;
|
}
|
}
|
|
|
void
|
void
|
fill_ent (ent, path)
|
fill_ent (ent, path)
|
ENT *ent;
|
ENT *ent;
|
char *path;
|
char *path;
|
{
|
{
|
char *first = path;
|
char *first = path;
|
char *null = path + strlen (path);
|
char *null = path + strlen (path);
|
char *last_slash = strrchr (path, '/');
|
char *last_slash = strrchr (path, '/');
|
char *cp, *dp;
|
char *cp, *dp;
|
int dots_seen, chars_seen;
|
int dots_seen, chars_seen;
|
|
|
if (last_slash + 1 == null)
|
if (last_slash + 1 == null)
|
{
|
{
|
*--null = '\0';
|
*--null = '\0';
|
last_slash = strrchr (path, '/');
|
last_slash = strrchr (path, '/');
|
}
|
}
|
|
|
if (!last_slash)
|
if (!last_slash)
|
{
|
{
|
last_slash = first - 1;
|
last_slash = first - 1;
|
}
|
}
|
|
|
if (null - last_slash < 13)
|
if (null - last_slash < 13)
|
ent->dos_name = (char *) xmalloc (null - last_slash);
|
ent->dos_name = (char *) xmalloc (null - last_slash);
|
else
|
else
|
ent->dos_name = (char *) xmalloc (13);
|
ent->dos_name = (char *) xmalloc (13);
|
ent->full_name = (char *) xmalloc (null - last_slash);
|
ent->full_name = (char *) xmalloc (null - last_slash);
|
ent->path = (char *) xmalloc (last_slash - first + 1);
|
ent->path = (char *) xmalloc (last_slash - first + 1);
|
|
|
strcpy (ent->full_name, last_slash + 1);
|
strcpy (ent->full_name, last_slash + 1);
|
if (last_slash > first)
|
if (last_slash > first)
|
{
|
{
|
strncpy (ent->path, first, last_slash - first);
|
strncpy (ent->path, first, last_slash - first);
|
ent->path[last_slash - first] = '\0';
|
ent->path[last_slash - first] = '\0';
|
}
|
}
|
else
|
else
|
ent->path = "\0";
|
ent->path = "\0";
|
|
|
cp = last_slash + 1;
|
cp = last_slash + 1;
|
dp = ent->dos_name;
|
dp = ent->dos_name;
|
dots_seen = 0;
|
dots_seen = 0;
|
chars_seen = 0;
|
chars_seen = 0;
|
while (1)
|
while (1)
|
{
|
{
|
if (!*cp)
|
if (!*cp)
|
break;
|
break;
|
switch (*cp)
|
switch (*cp)
|
{
|
{
|
case '.':
|
case '.':
|
if (cp == last_slash + 1 && strcmp (last_slash + 1, "."))
|
if (cp == last_slash + 1 && strcmp (last_slash + 1, "."))
|
{
|
{
|
invalid_msg ();
|
invalid_msg ();
|
printf ("%s - file name cannot start with dot\n", path);
|
printf ("%s - file name cannot start with dot\n", path);
|
*dp = 0;
|
*dp = 0;
|
break;
|
break;
|
}
|
}
|
if (dots_seen == 1)
|
if (dots_seen == 1)
|
{
|
{
|
/* If trailing dot, it will be ignored by MSDOG, so don't */
|
/* If trailing dot, it will be ignored by MSDOG, so don't */
|
/* actually complain. */
|
/* actually complain. */
|
if (*(cp + 1) != NULL)
|
if (*(cp + 1) != NULL)
|
{
|
{
|
invalid_msg ();
|
invalid_msg ();
|
printf ("%s - too many dots\n", path);
|
printf ("%s - too many dots\n", path);
|
}
|
}
|
*dp = '\0';
|
*dp = '\0';
|
break;
|
break;
|
}
|
}
|
*dp++ = '.';
|
*dp++ = '.';
|
chars_seen = 0;
|
chars_seen = 0;
|
dots_seen++;
|
dots_seen++;
|
break;
|
break;
|
case '"':
|
case '"':
|
case '*':
|
case '*':
|
case '+':
|
case '+':
|
case ',':
|
case ',':
|
case ';':
|
case ';':
|
case '<':
|
case '<':
|
case '=':
|
case '=':
|
case '>':
|
case '>':
|
case '?':
|
case '?':
|
case '[':
|
case '[':
|
case '\\':
|
case '\\':
|
case ']':
|
case ']':
|
case '|':
|
case '|':
|
case ':':
|
case ':':
|
invalid_msg ();
|
invalid_msg ();
|
printf ("%s - invalid character `%c'\n", path, *cp);
|
printf ("%s - invalid character `%c'\n", path, *cp);
|
*dp++ = '?';
|
*dp++ = '?';
|
chars_seen++;
|
chars_seen++;
|
break;
|
break;
|
default:
|
default:
|
if (dots_seen)
|
if (dots_seen)
|
{
|
{
|
if (chars_seen >= 3)
|
if (chars_seen >= 3)
|
break;
|
break;
|
}
|
}
|
else if (chars_seen >= 8)
|
else if (chars_seen >= 8)
|
break;
|
break;
|
if ((*cp <= ' ') || (*cp >= 0x7f))
|
if ((*cp <= ' ') || (*cp >= 0x7f))
|
{
|
{
|
invalid_msg ();
|
invalid_msg ();
|
printf ("%s - invalid character `%c'\n", path, *cp);
|
printf ("%s - invalid character `%c'\n", path, *cp);
|
*dp++ = '?';
|
*dp++ = '?';
|
chars_seen++;
|
chars_seen++;
|
break;
|
break;
|
}
|
}
|
if (islower (*cp))
|
if (islower (*cp))
|
*dp++ = toupper (*cp);
|
*dp++ = toupper (*cp);
|
else
|
else
|
*dp++ = *cp;
|
*dp++ = *cp;
|
chars_seen++;
|
chars_seen++;
|
break;
|
break;
|
}
|
}
|
cp++;
|
cp++;
|
}
|
}
|
*dp++ = '\0';
|
*dp++ = '\0';
|
}
|
}
|
|
|
int
|
int
|
compare_ent_dosname (e1, e2)
|
compare_ent_dosname (e1, e2)
|
ENT **e1;
|
ENT **e1;
|
ENT **e2;
|
ENT **e2;
|
{
|
{
|
int r = strcmp ((*e1)->dos_name, (*e2)->dos_name);
|
int r = strcmp ((*e1)->dos_name, (*e2)->dos_name);
|
if (r == 0)
|
if (r == 0)
|
r = strcmp ((*e1)->path, (*e2)->path);
|
r = strcmp ((*e1)->path, (*e2)->path);
|
if (r == 0)
|
if (r == 0)
|
r = strcmp ((*e1)->full_name, (*e2)->full_name);
|
r = strcmp ((*e1)->full_name, (*e2)->full_name);
|
return r;
|
return r;
|
}
|
}
|
|
|
int
|
int
|
compare_ent_fullname (e1, e2)
|
compare_ent_fullname (e1, e2)
|
ENT **e1;
|
ENT **e1;
|
ENT **e2;
|
ENT **e2;
|
{
|
{
|
int r = strncmp ((*e1)->full_name, (*e2)->full_name, 14);
|
int r = strncmp ((*e1)->full_name, (*e2)->full_name, 14);
|
if (r == 0)
|
if (r == 0)
|
r = strcmp ((*e1)->path, (*e2)->path);
|
r = strcmp ((*e1)->path, (*e2)->path);
|
if (r == 0)
|
if (r == 0)
|
r = strcmp ((*e1)->full_name, (*e2)->full_name);
|
r = strcmp ((*e1)->full_name, (*e2)->full_name);
|
return r;
|
return r;
|
}
|
}
|
|
|
char *
|
char *
|
mpath (ent)
|
mpath (ent)
|
ENT *ent;
|
ENT *ent;
|
{
|
{
|
static char buf[1024]; /* fixed sizes for buffers are bad! */
|
static char buf[1024]; /* fixed sizes for buffers are bad! */
|
if (ent->path && ent->path[0])
|
if (ent->path && ent->path[0])
|
sprintf (buf, "%s/%s", ent->path, ent->full_name);
|
sprintf (buf, "%s/%s", ent->path, ent->full_name);
|
else
|
else
|
return ent->full_name;
|
return ent->full_name;
|
return buf;
|
return buf;
|
}
|
}
|
|
|
/****************************************************************\
|
/****************************************************************\
|
* List handling routines *
|
* List handling routines *
|
\****************************************************************/
|
\****************************************************************/
|
|
|
void
|
void
|
add_ent (ent)
|
add_ent (ent)
|
ENT *ent;
|
ENT *ent;
|
{
|
{
|
ent->next = eroot;
|
ent->next = eroot;
|
eroot = ent;
|
eroot = ent;
|
}
|
}
|
|
|
void
|
void
|
handle_input (line)
|
handle_input (line)
|
char *line;
|
char *line;
|
{
|
{
|
ENT *ent = alloc_ent ();
|
ENT *ent = alloc_ent ();
|
fill_ent (ent, line);
|
fill_ent (ent, line);
|
add_ent (ent);
|
add_ent (ent);
|
}
|
}
|
|
|
void
|
void
|
display_problems ()
|
display_problems ()
|
{
|
{
|
ENT **elist, *ent;
|
ENT **elist, *ent;
|
int ecount, i, first, first_err;
|
int ecount, i, first, first_err;
|
char **dos_dev_name;
|
char **dos_dev_name;
|
|
|
for (ecount = 0, ent = eroot; ent; ent = ent->next, ecount++);
|
for (ecount = 0, ent = eroot; ent; ent = ent->next, ecount++);
|
elist = (ENT **) xmalloc (sizeof (ENT *) * ecount);
|
elist = (ENT **) xmalloc (sizeof (ENT *) * ecount);
|
for (ecount = 0, ent = eroot; ent; ent = ent->next, ecount++)
|
for (ecount = 0, ent = eroot; ent; ent = ent->next, ecount++)
|
elist[ecount] = ent;
|
elist[ecount] = ent;
|
|
|
qsort (elist, ecount, sizeof (ENT *), compare_ent_dosname);
|
qsort (elist, ecount, sizeof (ENT *), compare_ent_dosname);
|
|
|
first_err = 1;
|
first_err = 1;
|
for (i = 0; i < ecount; i++)
|
for (i = 0; i < ecount; i++)
|
{
|
{
|
int elist_len = strlen (elist[i]->dos_name);
|
int elist_len = strlen (elist[i]->dos_name);
|
|
|
dos_dev_name = dos_special_names;
|
dos_dev_name = dos_special_names;
|
while (*dos_dev_name)
|
while (*dos_dev_name)
|
{
|
{
|
if ((strcmp (elist[i]->dos_name, *dos_dev_name) == 0)
|
if ((strcmp (elist[i]->dos_name, *dos_dev_name) == 0)
|
|| ((*(elist[i]->dos_name + elist_len - 1) == '.')
|
|| ((*(elist[i]->dos_name + elist_len - 1) == '.')
|
&& (strncmp (elist[i]->dos_name, *dos_dev_name, elist_len - 2) == 0)))
|
&& (strncmp (elist[i]->dos_name, *dos_dev_name, elist_len - 2) == 0)))
|
{
|
{
|
if (first_err)
|
if (first_err)
|
{
|
{
|
if (first_msg)
|
if (first_msg)
|
first_msg = 0;
|
first_msg = 0;
|
else
|
else
|
putchar ('\n');
|
putchar ('\n');
|
printf ("The following resolve to special DOS device names:\n");
|
printf ("The following resolve to special DOS device names:\n");
|
first_err = 0;
|
first_err = 0;
|
}
|
}
|
printf ("%-14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
|
printf ("%-14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
|
break;
|
break;
|
}
|
}
|
dos_dev_name++;
|
dos_dev_name++;
|
}
|
}
|
}
|
}
|
|
|
first = 1;
|
first = 1;
|
first_err = 1;
|
first_err = 1;
|
for (i = 0; i < ecount - 1; i++)
|
for (i = 0; i < ecount - 1; i++)
|
{
|
{
|
int elist1_len = strlen (elist[i + 1]->dos_name);
|
int elist1_len = strlen (elist[i + 1]->dos_name);
|
|
|
if (((strcmp (elist[i]->dos_name, elist[i + 1]->dos_name) == 0)
|
if (((strcmp (elist[i]->dos_name, elist[i + 1]->dos_name) == 0)
|
&& (strcmp (elist[i]->path, elist[i + 1]->path) == 0))
|
&& (strcmp (elist[i]->path, elist[i + 1]->path) == 0))
|
|| ((*(elist[i + 1]->dos_name + elist1_len - 1) == '.')
|
|| ((*(elist[i + 1]->dos_name + elist1_len - 1) == '.')
|
&& (strncmp (elist[i]->dos_name, elist[i + 1]->dos_name, elist1_len - 2) == 0)))
|
&& (strncmp (elist[i]->dos_name, elist[i + 1]->dos_name, elist1_len - 2) == 0)))
|
{
|
{
|
if (first_err)
|
if (first_err)
|
{
|
{
|
if (first_msg)
|
if (first_msg)
|
first_msg = 0;
|
first_msg = 0;
|
else
|
else
|
putchar ('\n');
|
putchar ('\n');
|
printf ("The following resolve to the same DOS file names:\n");
|
printf ("The following resolve to the same DOS file names:\n");
|
first_err = 0;
|
first_err = 0;
|
}
|
}
|
if (first)
|
if (first)
|
{
|
{
|
printf ("%-14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
|
printf ("%-14s : %s\n", elist[i]->dos_name, mpath (elist[i]));
|
first = 0;
|
first = 0;
|
}
|
}
|
printf ("\t\t %s\n", mpath (elist[i + 1]));
|
printf ("\t\t %s\n", mpath (elist[i + 1]));
|
}
|
}
|
else
|
else
|
first = 1;
|
first = 1;
|
}
|
}
|
|
|
qsort (elist, ecount, sizeof (ENT *), compare_ent_fullname);
|
qsort (elist, ecount, sizeof (ENT *), compare_ent_fullname);
|
|
|
first = 1;
|
first = 1;
|
first_err = 1;
|
first_err = 1;
|
for (i = 0; i < ecount - 1; i++)
|
for (i = 0; i < ecount - 1; i++)
|
{
|
{
|
if ((strncmp (elist[i]->full_name, elist[i + 1]->full_name, 14) == 0) &&
|
if ((strncmp (elist[i]->full_name, elist[i + 1]->full_name, 14) == 0) &&
|
(strcmp (elist[i]->path, elist[i + 1]->path) == 0))
|
(strcmp (elist[i]->path, elist[i + 1]->path) == 0))
|
{
|
{
|
if (first_err)
|
if (first_err)
|
{
|
{
|
if (first_msg)
|
if (first_msg)
|
first_msg = 0;
|
first_msg = 0;
|
else
|
else
|
putchar ('\n');
|
putchar ('\n');
|
printf ("The following resolve to the same SysV file names:\n");
|
printf ("The following resolve to the same SysV file names:\n");
|
first_err = 0;
|
first_err = 0;
|
}
|
}
|
if (first)
|
if (first)
|
{
|
{
|
printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
|
printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
|
first = 0;
|
first = 0;
|
elist[i]->tagged = 1;
|
elist[i]->tagged = 1;
|
}
|
}
|
printf ("\t\t %s\n", mpath (elist[i + 1]));
|
printf ("\t\t %s\n", mpath (elist[i + 1]));
|
elist[i + 1]->tagged = 1;
|
elist[i + 1]->tagged = 1;
|
}
|
}
|
else
|
else
|
first = 1;
|
first = 1;
|
}
|
}
|
|
|
first_err = 1;
|
first_err = 1;
|
for (i = 0; i < ecount; i++)
|
for (i = 0; i < ecount; i++)
|
{
|
{
|
if ((strlen (elist[i]->full_name) > 14) && !elist[i]->tagged)
|
if ((strlen (elist[i]->full_name) > 14) && !elist[i]->tagged)
|
{
|
{
|
if (first_err)
|
if (first_err)
|
{
|
{
|
if (first_msg)
|
if (first_msg)
|
first_msg = 0;
|
first_msg = 0;
|
else
|
else
|
putchar ('\n');
|
putchar ('\n');
|
printf ("The following file names are too long for SysV:\n");
|
printf ("The following file names are too long for SysV:\n");
|
first_err = 0;
|
first_err = 0;
|
}
|
}
|
printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
|
printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i]));
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/****************************************************************\
|
/****************************************************************\
|
* Main entry point *
|
* Main entry point *
|
\****************************************************************/
|
\****************************************************************/
|
|
|
main (argc, argv)
|
main (argc, argv)
|
int argc;
|
int argc;
|
char **argv;
|
char **argv;
|
{
|
{
|
FILE *input = stdin;
|
FILE *input = stdin;
|
if (argc > 1)
|
if (argc > 1)
|
{
|
{
|
input = fopen (argv[1], "r");
|
input = fopen (argv[1], "r");
|
if (!input)
|
if (!input)
|
{
|
{
|
perror (argv[1]);
|
perror (argv[1]);
|
exit (1);
|
exit (1);
|
}
|
}
|
}
|
}
|
while (1)
|
while (1)
|
{
|
{
|
char line[500];
|
char line[500];
|
char *lp;
|
char *lp;
|
fgets (line, 500, input);
|
fgets (line, 500, input);
|
if (feof (input))
|
if (feof (input))
|
break;
|
break;
|
lp = line + strlen (line);
|
lp = line + strlen (line);
|
while ((lp != line) && (*lp <= ' '))
|
while ((lp != line) && (*lp <= ' '))
|
lp--;
|
lp--;
|
lp[1] = 0;
|
lp[1] = 0;
|
handle_input (line);
|
handle_input (line);
|
}
|
}
|
display_problems ();
|
display_problems ();
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* End of file */
|
/* End of file */
|
|
|