--- /dev/null
+%define prefix /usr
+%define ver 3.0.1.6
+Summary: Splint - A tool for statically checking C programs
+Name: splint
+Version: %ver
+Release: 1
+Copyright: MIT
+Url: http://www.splint.org
+
+Packager: Heiko Abraham, abrahamh@web.de
+Group: Development/Languages
+Source: %{name}-%{ver}.src.tgz
+
+BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root
+Requires: gcc
+
+
+
+
+
+%description
+Splint is a tool for statically checking C programs for security vulnerabilities
+and common programming mistakes. With minimal effort, Splint can be used as a
+better lint(1).If additional effort is invested adding annotations to programs,
+Splint can perform stronger checks than can be done by any standard lint. For
+full documentation, please see http://www.splint.org.
+
+Please set environment variables:
+- LARCH_PATH=%{prefix}/share/splint/lib
+ and
+- LCLIMPORTDIR=%{prefix}/share/splint/imports
+.
+
+%prep
+%setup -q
+
+%build
+CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix}
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT%{prefix}/bin
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/doc/%{name}-%{PACKAGE_VERSION}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/splint/imports
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/splint/lib
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/man/man1
+
+make DESTDIR=$RPM_BUILD_ROOT install
+
+# now install docs, why 'make install' will not do this
+cp README $RPM_BUILD_ROOT%{prefix}/share/doc/%{name}-%{PACKAGE_VERSION}
+cp doc/*.html $RPM_BUILD_ROOT%{prefix}/share/doc/%{name}-%{PACKAGE_VERSION}
+cp doc/*.pdf $RPM_BUILD_ROOT%{prefix}/share/doc/%{name}-%{PACKAGE_VERSION}
+
+
+
+%post
+
+%preun
+
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT/*
+rm -rf $RPM_BUILD_DIR/%{name}-%{PACKAGE_VERSION}/*
+
+
+
+
+%files
+%{prefix}/bin/splint
+%{prefix}/share/splint/imports/*
+%{prefix}/share/splint/lib/*
+%{prefix}/share/doc/%{name}-%{PACKAGE_VERSION}/*
+
+
+
+
+
+
typedef enum
{
+ MODENAME_FLAG = -3,
SKIP_FLAG = -2,
INVALID_FLAG = -1,
# include "flag_codes.gen"
extern bool flagcode_isSkip (flagcode p_f) /*@*/ ;
# define flagcode_isSkip(f) ((f) == SKIP_FLAG)
+extern bool flagcode_isModeName (flagcode p_f) /*@*/ ;
+# define flagcode_isModeName(f) ((f) == MODENAME_FLAG)
+
extern bool flagcode_isValid (flagcode p_f) /*@*/ ;
# define flagcode_isValid(f) ((f) != INVALID_FLAG)
/*@constant observer cstring DEFAULT_MODE;@*/
# define DEFAULT_MODE (cstring_makeLiteralTemp ("standard"))
-extern void flags_initMod (void) /*@modifies internalState@*/ ;
-
-extern bool isMode (cstring p_s) /*@*/ ;
+extern bool flags_isModeName (cstring p_s) /*@*/ ;
extern /*@only@*/ cstring describeModes (void) /*@modifies g_messagestream@*/ ;
extern void summarizeErrors (void) /*@modifies g_messagestream@*/ ;
extern bool flagcode_isSpecialFlag (flagcode p_f) /*@*/ ;
extern bool flagcode_isGlobalFlag (flagcode p_f) /*@*/ ;
extern bool flagcode_isMessageControlFlag (flagcode p_f) /*@*/ ;
-
+extern bool flagcode_isHelpFlag (flagcode p_f) /*@*/ ;
+
+extern void flags_initMod (void) /*@modifies internalState@*/ ;
+
+extern bool flags_processFlags (int p_argc, char **p_argv)
+ /*@requires maxRead(p_argv) >= p_argc - 1@*/
+ /* returns true if normal, false if execution should exit */ ;
+
# else
# error "Multiple include"
# endif
return (flags[f].main == FK_NAMES);
}
+bool flagcode_isHelpFlag (flagcode f)
+{
+ return f == FLG_HELP;
+}
+
bool flagcode_isMessageControlFlag (flagcode f)
{
/*
}
else
{
- if (isMode (flagname))
+ if (flags_isModeName (flagname))
{
cstring_free (oflagname);
if (cstring_firstChar (s) == 'I')
{
- return FLG_INCLUDEPATH; /* no space after -I */
+ return FLG_INCLUDEPATH; /* no space required after -I */
}
if (cstring_firstChar (s) == 'S')
{
- return FLG_SPECPATH; /* no space after -S */
+ return FLG_SPECPATH; /* no space required after -S */
}
if (cstring_firstChar (s) == 'D')
{
- return FLG_DEFINE; /* no space after -D */
+ return FLG_DEFINE; /* no space required after -D */
}
if (cstring_firstChar (s) == 'U')
{
- return FLG_UNDEFINE; /* no space after -D */
+ return FLG_UNDEFINE; /* no space required after -D */
}
cflag = canonicalizeFlag (s);
res = SKIP_FLAG;
}
+ else if (flags_isModeName (cflag))
+ {
+ res = MODENAME_FLAG;
else
{
res = INVALID_FLAG;
# endif
bool
-isMode (cstring s)
+flags_isModeName (cstring s)
{
allModes (modename)
{
}
}
+bool flags_processFlags (bool inCommandLine, int argc, char **argv)
+{
+ int i;
+
+ for (i = 0; i < argc; i++)
+ {
+ char *thisarg = argv[i];
+
+ if (*thisarg == '-' || *thisarg == '+')
+ {
+ bool set = (*thisarg == '+');
+ cstring flagname = cstring_fromChars (thisarg + 1); /* skip '-' or '+' */
+ flagcode opt = flags_identifyFlag (flagname);
+
+ DPRINTF (("Flag: %s", flagcode_unparse (opt)));
+
+ if (flagcode_isInvalid (opt))
+ {
+ DPRINTF (("Error!"));
+ voptgenerror (FLG_BADFLAG,
+ message ("Unrecognized option: %s",
+ cstring_fromChars (thisarg)),
+ g_currentloc);
+ }
+ else if (flagcode_isHelpFlag (opt))
+ {
+ if (inCommandLine)
+ {
+ voptgenerror (FLG_BADFLAG,
+ message ("Help flag must be first on the command line: %s",
+ cstring_fromChars (thisarg)),
+ g_currentloc);
+ }
+ else
+ {
+ voptgenerror (FLG_BADFLAG,
+ message ("Help flags can only be used on the command line: %s",
+ cstring_fromChars (thisarg)),
+ g_currentloc);
+ }
+ }
+ else if (flagcode_isModeNameFlag (opt))
+ {
+ context_setMode (flagname);
+ }
+ else if (flagcode_isMessageControlFlag (opt))
+ {
+ /*
+ ** Processed on first pass
+ */
+
+ if (flagcode_hasArgument (opt))
+ {
+ ++i;
+ }
+ }
+ else
+ {
+ /*
+ ** A normal control flag
+ */
+
+ context_userSetFlag (opt, set);
+
+ if (flagcode_hasArgument (opt))
+ {
+ if (flagcode_isPassThrough (opt)) /* -D or -U */
+ {
+ /*
+ ** Following space is optional
+ */
+
+ flags_recordPassThroughArg (flagname);
+
+ passThroughArgs = cstringSList_add
+ (passThroughArgs, cstring_fromChars (thisarg));
+ }
+ else if (flagcode_hasNumber (opt))
+ {
+ if (++i < argc)
+ {
+ setValueFlag (opt, cstring_fromChars (argv[i]));
+ }
+ else
+ {
+ llfatalerror
+ (message
+ ("Flag %s must be followed by a number",
+ flagcode_unparse (opt)));
+ }
+ }
+ else if (flagcode_hasChar (opt))
+ {
+ if (++i < argc)
+ {
+ setValueFlag (opt, cstring_fromChars (argv[i]));
+ }
+ else
+ {
+ llfatalerror
+ (message
+ ("Flag %s must be followed by a character",
+ flagcode_unparse (opt)));
+ }
+ }
+ else if (opt == FLG_INCLUDEPATH || opt == FLG_SPECPATH)
+ {
+ cstring dir = cstring_suffix (cstring_fromChars (thisarg), 1); /* skip over I */
+
+ switch (opt)
+ {
+ case FLG_INCLUDEPATH:
+ cppAddIncludeDir (dir);
+ /*@switchbreak@*/ break;
+ case FLG_SPECPATH:
+ /*@-mustfree@*/
+ g_localSpecPath = cstring_toCharsSafe
+ (message ("%s%h%s",
+ cstring_fromChars (g_localSpecPath),
+ PATH_SEPARATOR,
+ dir));
+ /*@=mustfree@*/
+ /*@switchbreak@*/ break;
+ BADDEFAULT;
+ }
+ }
+ else if (flagcode_hasString (opt)
+ || opt == FLG_INIT || opt == FLG_OPTF)
+ {
+ if (++i < argc)
+ {
+ cstring arg = cstring_fromChars (argv[i]);
+
+ if (opt == FLG_OPTF)
+ {
+ ; /* -f already processed */
+ }
+ else if (opt == FLG_INIT)
+ {
+# ifndef NOLCL
+ initFile = inputStream_create
+ (arg,
+ cstring_makeLiteralTemp (LCLINIT_SUFFIX),
+ FALSE);
+# endif
+ break;
+ }
+ else
+ {
+ DPRINTF (("String flag: %s / %s",
+ flagcode_unparse (opt), arg));
+ if (opt == FLG_MTSFILE)
+ {
+ /*
+ ** arg identifies mts files
+ */
+ cstring tmp = message ("%s%s", arg, MTS_EXTENSION);
+ addLarchPathFile (mtfiles, tmp);
+ cstring_free (tmp);
+ tmp = message ("%s%s", arg, XH_EXTENSION);
+ addXHFile (xfiles, tmp);
+ cstring_free (tmp);
+ }
+ else
+ {
+ setStringFlag (opt, cstring_copy (arg));
+ }
+ }
+ }
+ else
+ {
+ llfatalerror
+ (message
+ ("Flag %s must be followed by a string",
+ flagcode_unparse (opt)));
+ }
+ }
+ else
+ {
+ /* no argument */
+ }
+ }
+ }
+ }
+ else /* its a filename */
+ {
+ DPRINTF (("Adding filename: %s", thisarg));
+ fl = cstringSList_add (fl, cstring_fromChars (thisarg));
+ }
+ }
+ }
+}
+
+void flags_processHelp (int argc, char **argv)
+{
+
+
+ if (showhelp)
+ {
+ if (allhelp)
+ {
+ showHerald ();
+ }
+
+ allhelp = FALSE;
+
+ if (*thisarg == '-' || *thisarg == '+')
+ {
+ thisarg++; /* skip '-' */
+ }
+ if (mstring_equal (thisarg, "modes"))
+ {
+ llmsg (describeModes ());
+ }
+ else if (mstring_equal (thisarg, "vars") || mstring_equal (thisarg, "env"))
+ {
+ describeVars ();
+ }
+ else if (mstring_equal (thisarg, "annotations"))
+ {
+ printAnnotations ();
+ }
+ else if (mstring_equal (thisarg, "parseerrors"))
+ {
+ printParseErrors ();
+ }
+ else if (mstring_equal (thisarg, "comments"))
+ {
+ printComments ();
+ }
+ else if (mstring_equal (thisarg, "prefixcodes"))
+ {
+ describePrefixCodes ();
+ }
+ else if (mstring_equal (thisarg, "references")
+ || mstring_equal (thisarg, "refs"))
+ {
+ printReferences ();
+ }
+ else if (mstring_equal (thisarg, "mail"))
+ {
+ printMail ();
+ }
+ else if (mstring_equal (thisarg, "maintainer")
+ || mstring_equal (thisarg, "version"))
+ {
+ printMaintainer ();
+ }
+ else if (mstring_equal (thisarg, "flags"))
+ {
+ if (i + 1 < argc)
+ {
+ char *next = argv[i + 1];
+
+ if (specialFlagsHelp (next))
+ {
+ i++;
+ }
+ else
+ {
+ flagkind k = identifyCategory (cstring_fromChars (next));
+
+ if (k != FK_NONE)
+ {
+ printCategory (k);
+ i++;
+ }
+ }
+ }
+ else
+ {
+ printFlags ();
+ }
+ }
+ else
+ {
+ cstring s = describeFlag (cstring_fromChars (thisarg));
+
+ if (cstring_isDefined (s))
+ {
+ llmsg (s);
+ }
+ }
+ }
+ else
+ {
# endif
{
bool first_time = TRUE;
- bool showhelp = FALSE;
- bool allhelp = TRUE;
bool expsuccess;
inputStream sourceFile = inputStream_undefined;
if (argc <= 1)
{
showHelp ();
- llexit (LLGIVEUP);
+ llexit (LLSUCCESS);
+ }
+
+ /* -help must be the first flag to get help */
+ if (flagcode_isHelpFlag (flags_identifyFlag (argv[1])))
+ {
+ flags_processHelp (argc - 1, argv + 1);
+ llexit (LLSUCCESS);
}
setCodePoint ();
{
/* Put C_INCLUDE_PATH directories in sysdirs */
cstring cincval = osd_getEnvironmentVariable (cstring_makeLiteralTemp ("C_INCLUDE_PATH"));
+
if (cstring_isDefined (cincval))
{
context_setString (FLG_SYSTEMDIRS, cstring_copy (cincval));
}
setCodePoint ();
-
- for (i = 1; i < argc; i++)
- {
- char *thisarg;
- flagcode opt;
-
- thisarg = argv[i];
-
- if (showhelp)
- {
- if (allhelp)
- {
- showHerald ();
- }
-
- allhelp = FALSE;
-
- if (*thisarg == '-' || *thisarg == '+')
- {
- thisarg++; /* skip '-' */
- }
- if (mstring_equal (thisarg, "modes"))
- {
- llmsg (describeModes ());
- }
- else if (mstring_equal (thisarg, "vars")
- || mstring_equal (thisarg, "env"))
- {
- describeVars ();
- }
- else if (mstring_equal (thisarg, "annotations"))
- {
- printAnnotations ();
- }
- else if (mstring_equal (thisarg, "parseerrors"))
- {
- printParseErrors ();
- }
- else if (mstring_equal (thisarg, "comments"))
- {
- printComments ();
- }
- else if (mstring_equal (thisarg, "prefixcodes"))
- {
- describePrefixCodes ();
- }
- else if (mstring_equal (thisarg, "references")
- || mstring_equal (thisarg, "refs"))
- {
- printReferences ();
- }
- else if (mstring_equal (thisarg, "mail"))
- {
- printMail ();
- }
- else if (mstring_equal (thisarg, "maintainer")
- || mstring_equal (thisarg, "version"))
- {
- printMaintainer ();
- }
- else if (mstring_equal (thisarg, "flags"))
- {
- if (i + 1 < argc)
- {
- char *next = argv[i + 1];
-
- if (specialFlagsHelp (next))
- {
- i++;
- }
- else
- {
- flagkind k = identifyCategory (cstring_fromChars (next));
-
- if (k != FK_NONE)
- {
- printCategory (k);
- i++;
- }
- }
- }
- else
- {
- printFlags ();
- }
- }
- else
- {
- cstring s = describeFlag (cstring_fromChars (thisarg));
-
- if (cstring_isDefined (s))
- {
- llmsg (s);
- }
- }
- }
- else
- {
- if (*thisarg == '-' || *thisarg == '+')
- {
- bool set = (*thisarg == '+');
- cstring flagname;
-
- thisarg++; /* skip '-' */
- flagname = cstring_fromChars (thisarg);
-
- DPRINTF (("Flag: %s", flagname));
- opt = flags_identifyFlag (flagname);
- DPRINTF (("Flag: %s", flagcode_unparse (opt)));
- if (flagcode_isMessageControlFlag (opt))
- {
- /*
- ** Processed on first pass
- */
-
- if (flagcode_hasArgument (opt))
- {
- ++i;
- }
- }
- else if (flagcode_isInvalid (opt))
- {
- DPRINTF (("Invalid: %s", flagname));
-
- if (isMode (flagname))
- {
- context_setMode (flagname);
- }
- else
- {
- DPRINTF (("Error!"));
- voptgenerror (FLG_BADFLAG,
- message ("Unrecognized option: %s",
- cstring_fromChars (thisarg)),
- g_currentloc);
- }
- }
- else
- {
- context_userSetFlag (opt, set);
-
- if (flagcode_hasArgument (opt))
- {
- if (opt == FLG_HELP)
- {
- showhelp = TRUE;
- }
- else if (flagcode_isPassThrough (opt)) /* -D or -U */
- {
- passThroughArgs = cstringSList_add
- (passThroughArgs, cstring_fromChars (thisarg));
- }
- else if (flagcode_hasNumber (opt))
- {
- if (++i < argc)
- {
- setValueFlag (opt, cstring_fromChars (argv[i]));
- }
- else
- {
- llfatalerror
- (message
- ("Flag %s must be followed by a number",
- flagcode_unparse (opt)));
- }
- }
- else if (flagcode_hasChar (opt))
- {
- if (++i < argc)
- {
- setValueFlag (opt, cstring_fromChars (argv[i]));
- }
- else
- {
- llfatalerror
- (message
- ("Flag %s must be followed by a character",
- flagcode_unparse (opt)));
- }
- }
- else if (opt == FLG_INCLUDEPATH || opt == FLG_SPECPATH)
- {
- cstring dir = cstring_suffix (cstring_fromChars (thisarg), 1); /* skip over I */
-
- switch (opt)
- {
- case FLG_INCLUDEPATH:
- cppAddIncludeDir (dir);
- /*@switchbreak@*/ break;
- case FLG_SPECPATH:
- /*@-mustfree@*/
- g_localSpecPath = cstring_toCharsSafe
- (message ("%s%h%s",
- cstring_fromChars (g_localSpecPath),
- PATH_SEPARATOR,
- dir));
- /*@=mustfree@*/
- /*@switchbreak@*/ break;
- BADDEFAULT;
- }
- }
- else if (flagcode_hasString (opt)
- || opt == FLG_INIT || opt == FLG_OPTF)
- {
- if (++i < argc)
- {
- cstring arg = cstring_fromChars (argv[i]);
-
- if (opt == FLG_OPTF)
- {
- ; /* -f already processed */
- }
- else if (opt == FLG_INIT)
- {
-# ifndef NOLCL
- initFile = inputStream_create
- (arg,
- cstring_makeLiteralTemp (LCLINIT_SUFFIX),
- FALSE);
-# endif
- break;
- }
- else
- {
- DPRINTF (("String flag: %s / %s",
- flagcode_unparse (opt), arg));
- if (opt == FLG_MTSFILE)
- {
- /*
- ** arg identifies mts files
- */
- cstring tmp = message ("%s%s", arg, MTS_EXTENSION);
- addLarchPathFile (mtfiles, tmp);
- cstring_free (tmp);
- tmp = message ("%s%s", arg, XH_EXTENSION);
- addXHFile (xfiles, tmp);
- cstring_free (tmp);
- }
- else
- {
- setStringFlag (opt, cstring_copy (arg));
- }
- }
- }
- else
- {
- llfatalerror
- (message
- ("Flag %s must be followed by a string",
- flagcode_unparse (opt)));
- }
- }
- else
- {
- /* no argument */
- }
- }
- }
- }
- else /* its a filename */
- {
- DPRINTF (("Adding filename: %s", thisarg));
- fl = cstringSList_add (fl, cstring_fromChars (thisarg));
- }
- }
- }
+ /* argv[0] is the program name, don't pass it to flags_processFlags */
+ flags_processFlags (argc - 1, argv + 1);
showHerald ();
{
DPRINTF (("Invalid: %s", thisflag));
- if (isMode (cstring_fromChars (thisflag)))
+ if (flags_isModeName (cstring_fromChars (thisflag)))
{
context_setMode (cstring_fromChars (thisflag));
}
else if (opt == FLG_INCLUDEPATH
|| opt == FLG_SPECPATH)
{
- cstring dir = cstring_suffix (cstring_fromChars (thisflag), 1); /* skip over I/S */
+ cstring dir;
+
+ /*
+ ** Either -I<dir> or -I <dir>
+ */
+
+ if (cstring_length (thisflag) > 1)
+ {
+ dir = cstring_suffix (cstring_fromChars (thisflag), 1); /* skip over I/S */
+ }
+ else
+ {
+ BADBRANCH; /*@!!!!@*/
+ }
switch (opt)
{