@node Coding Standards @appendix Coding Standards All of you should be familiar with good coding standards by now. This project will be much easier to complete and grade if you maintain a consistent code style and employ sensible variable naming policies. Code style makes up a significant part of your final grade for this work, and will be scrutinised carefully. We want to stress that aside from the fact that we are explicitly basing part of your grade on this, good coding practices will also improve the quality of your code. This makes it easier for your team-mates to interact with it and, ultimately, will improve your chances of having a good working program. The rest of this appendix will discuss the coding standards used in the existing PintOS codebase and how we expect you to interact with this. @menu * Coding Style:: * C99:: * Unsafe String Functions:: @end menu @comment ---------------------------------------------------------------------- @node Coding Style @section Style Style, for the purposes of our grading, refers to how readable your code is. At minimum, this means that your code is well formatted, your variable names are descriptive and your functions are decomposed and well commented. Any other factors which make it hard (or easy) for us to read or use your code will be reflected in your style grade. The existing PintOS code is written in the GNU style and largely follows the @uref{http://www.gnu.org/prep/standards_toc.html, , GNU Coding Standards}. We encourage you to follow the applicable parts of them too, especially chapter 5, ``Making the Best Use of C.'' Using a different style won't cause actual problems so long as you are self-consistent in your additions. It is ugly to see gratuitous differences in style from one function to another. If your code is too ugly, it will cost you points. Please limit C source file lines to at most 80 characters long. PintOS comments sometimes refer to external standards or specifications by writing a name inside square brackets, like this: @code{[IA32-v3a]}. These names refer to the reference names used in this documentation (@pxref{Bibliography}). If you remove existing PintOS code, please delete it from your source file entirely. Don't just put it into a comment or a conditional compilation directive, because that makes the resulting code hard to read. Version control software will allow you to recover the code if necessary later. We're only going to do a compile in the directory for the task being submitted. You don't need to make sure that the previous tasks also compile. Task code should be written so that all of the subproblems for the task function together, that is, without the need to rebuild with different macros defined, etc. If you decide to do any work beyond the spec that changes normal PintOS behaviour so as to interfere with grading, then you must implement it so that it only acts that way when given a special command-line option of the form @option{-@var{name}}, where @var{name} is a name of your choice. You can add such an option by modifying @func{parse_options} in @file{threads/init.c}. The introduction section (@pxref{Source Code}) describes some additional high-level coding style requirements. @comment ---------------------------------------------------------------------- @page @node C99 @section C99 The PintOS source code uses a few features of the ``C99'' standard library that were not in the original 1989 standard for C. Many programmers are unaware of these features, so we will describe them. The new features used in PintOS are mostly in new headers: @table @file @item Defines macros @code{bool}, a 1-bit type that takes on only the values 0 and 1, @code{true}, which expands to 1, and @code{false}, which expands to 0. @item On systems that support them, this header defines types @code{int@var{n}_t} and @code{uint@var{n}_t} for @var{n} = 8, 16, 32, 64, and possibly other values. These are 2's complement signed and unsigned types, respectively, with the given number of bits. On systems where it is possible, this header also defines types @code{intptr_t} and @code{uintptr_t}, which are integer types big enough to hold a pointer. On all systems, this header defines types @code{intmax_t} and @code{uintmax_t}, which are the system's signed and unsigned integer types with the widest ranges. For every signed integer type @code{@var{type}_t} defined here, as well as for @code{ptrdiff_t} defined in @file{}, this header also defines macros @code{@var{TYPE}_MAX} and @code{@var{TYPE}_MIN} that give the type's range. Similarly, for every unsigned integer type @code{@var{type}_t} defined here, as well as for @code{size_t} defined in @file{}, this header defines a @code{@var{TYPE}_MAX} macro giving its maximum value. @item @file{} provides no straightforward way to format the types it defines with @func{printf} and related functions. This header provides macros to help with that. For every @code{int@var{n}_t} defined by @file{}, it provides macros @code{PRId@var{n}} and @code{PRIi@var{n}} for formatting values of that type with @code{"%d"} and @code{"%i"}. Similarly, for every @code{uint@var{n}_t}, it provides @code{PRIo@var{n}}, @code{PRIu@var{n}}, @code{PRIx@var{n}}, and @code{PRIX@var{n}}. You use these something like this, taking advantage of the fact that the C compiler concatenates adjacent string literals: @example #include @dots{} int32_t value = @dots{}; printf ("value=%08"PRId32"\n", value); @end example @noindent (note that the @code{%08} format string above pads the output int to 8 significant figures). The @samp{%} is not supplied by the @code{PRI} macros. As shown above, you supply it yourself and follow it by any flags, field width, etc. @item The @func{printf} function has some new type modifiers for printing standard types: @table @samp @item j For @code{intmax_t} (e.g.@: @samp{%jd}) or @code{uintmax_t} (e.g.@: @samp{%ju}). @item z For @code{size_t} (e.g.@: @samp{%zu}). @item t For @code{ptrdiff_t} (e.g.@: @samp{%td}). @end table PintOS @func{printf} also implements a nonstandard @samp{'} flag that groups large numbers with commas to make them easier to read. @end table @comment ----------------------------------------------------------------------@page @node Unsafe String Functions @section Unsafe String Functions A few of the string functions declared in the standard @file{} and @file{} headers are notoriously unsafe. The worst offenders are intentionally not included in the PintOS C library: @table @code @item strcpy() When used carelessly this function can overflow the buffer reserved for its output string. Use @func{strlcpy} instead. Refer to comments in its source code in @code{lib/string.c} for documentation. @item strncpy() This function can leave its destination buffer without a null string terminator. It also has performance problems. Again, use @func{strlcpy}. @item strcat() Same issue as @func{strcpy}. Use @func{strlcat} instead. Again, refer to comments in its source code in @code{lib/string.c} for documentation. @item strncat() The meaning of its buffer size argument is surprising. Again, use @func{strlcat}. @item strtok() Uses global data, so it is unsafe in threaded programs such as kernels. Use @func{strtok_r} instead, and see its source code in @code{lib/string.c} for documentation and an example. @item sprintf() Same issue as @func{strcpy}. Use @func{snprintf} instead. Refer to comments in @code{lib/stdio.h} for documentation. @item vsprintf() Same issue as @func{strcpy}. Use @func{vsnprintf} instead. @end table If you try to use any of these functions, the error message will give you a hint by referring to an identifier like @code{dont_use_sprintf_use_snprintf}.