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