Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

niceprintf.c

Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright 1990, 1991, 1993, 1994 by AT&T, Lucent Technologies and Bellcore.
00003 
00004 Permission to use, copy, modify, and distribute this software
00005 and its documentation for any purpose and without fee is hereby
00006 granted, provided that the above copyright notice appear in all
00007 copies and that both that the copyright notice and this
00008 permission notice and warranty disclaimer appear in supporting
00009 documentation, and that the names of AT&T, Bell Laboratories,
00010 Lucent or Bellcore or any of their entities not be used in
00011 advertising or publicity pertaining to distribution of the
00012 software without specific, written prior permission.
00013 
00014 AT&T, Lucent and Bellcore disclaim all warranties with regard to
00015 this software, including all implied warranties of
00016 merchantability and fitness.  In no event shall AT&T, Lucent or
00017 Bellcore be liable for any special, indirect or consequential
00018 damages or any damages whatsoever resulting from loss of use,
00019 data or profits, whether in an action of contract, negligence or
00020 other tortious action, arising out of or in connection with the
00021 use or performance of this software.
00022 ****************************************************************/
00023 
00024 #include "defs.h"
00025 #include "names.h"
00026 #include "output.h"
00027 #ifndef KR_headers
00028 #include "stdarg.h"
00029 #endif
00030 
00031 #define TOO_LONG_INDENT (2 * tab_size)
00032 #define MAX_INDENT 44
00033 #define MIN_INDENT 22
00034 static int last_was_newline = 0;
00035 int sharp_line = 0;
00036 int indent = 0;
00037 int in_comment = 0;
00038 int in_define = 0;
00039  extern int gflag1;
00040  extern char filename[];
00041 
00042  static void ind_printf Argdcl((int, FILE*, char*, va_list));
00043 
00044  static void
00045 #ifdef KR_headers
00046 write_indent(fp, use_indent, extra_indent, start, end)
00047         FILE *fp;
00048         int use_indent;
00049         int extra_indent;
00050         char *start;
00051         char *end;
00052 #else
00053 write_indent(FILE *fp, int use_indent, int extra_indent, char *start, char *end)
00054 #endif
00055 {
00056     int ind, tab;
00057 
00058     if (sharp_line) {
00059         fprintf(fp, "#line %ld \"%s\"\n", lineno, filename);
00060         sharp_line = 0;
00061         }
00062     if (in_define == 1) {
00063         in_define = 2;
00064         use_indent = 0;
00065         }
00066     if (last_was_newline && use_indent) {
00067         if (*start == '\n') do {
00068                 putc('\n', fp);
00069                 if (++start > end)
00070                         return;
00071                 }
00072                 while(*start == '\n');
00073 
00074         ind = indent <= MAX_INDENT
00075                 ? indent
00076                 : MIN_INDENT + indent % (MAX_INDENT - MIN_INDENT);
00077 
00078         tab = ind + extra_indent;
00079 
00080         while (tab > 7) {
00081             putc ('\t', fp);
00082             tab -= 8;
00083         } /* while */
00084 
00085         while (tab-- > 0)
00086             putc (' ', fp);
00087     } /* if last_was_newline */
00088 
00089     while (start <= end)
00090         putc (*start++, fp);
00091 } /* write_indent */
00092 
00093 #ifdef KR_headers
00094 /*VARARGS2*/
00095   void
00096  margin_printf (fp, a, b, c, d, e, f, g)
00097   FILE *fp;
00098   char *a;
00099   long b, c, d, e, f, g;
00100 {
00101     ind_printf (0, fp, a, b, c, d, e, f, g);
00102 } /* margin_printf */
00103 
00104 /*VARARGS2*/
00105   void
00106  nice_printf (fp, a, b, c, d, e, f, g)
00107   FILE *fp;
00108   char *a;
00109   long b, c, d, e, f, g;
00110 {
00111     ind_printf (1, fp, a, b, c, d, e, f, g);
00112 } /* nice_printf */
00113 #define SPRINTF(x,a,b,c,d,e,f,g) sprintf(x,a,b,c,d,e,f,g)
00114 
00115 #else /* if (!defined(KR_HEADERS)) */
00116 
00117 #define SPRINTF(x,a,b,c,d,e,f,g) vsprintf(x,a,ap)
00118 
00119   void
00120  margin_printf(FILE *fp, char *fmt, ...)
00121 {
00122         va_list ap;
00123         va_start(ap,fmt);
00124         ind_printf(0, fp, fmt, ap);
00125         va_end(ap);
00126         }
00127 
00128   void
00129  nice_printf(FILE *fp, char *fmt, ...)
00130 {
00131         va_list ap;
00132         va_start(ap,fmt);
00133         ind_printf(1, fp, fmt, ap);
00134         va_end(ap);
00135         }
00136 #endif
00137 
00138 #define  max_line_len c_output_line_length
00139                 /* 74Number of characters allowed on an output
00140                                    line.  This assumes newlines are handled
00141                                    nicely, i.e. a newline after a full text
00142                                    line on a terminal is ignored */
00143 
00144 /* output_buf   holds the text of the next line to be printed.  It gets
00145    flushed when a newline is printed.   next_slot   points to the next
00146    available location in the output buffer, i.e. where the next call to
00147    nice_printf will have its output stored */
00148 
00149 static char *output_buf;
00150 static char *next_slot;
00151 static char *string_start;
00152 
00153 static char *word_start = NULL;
00154 static int cursor_pos = 0;
00155 static int In_string = 0;
00156 
00157  void
00158 np_init(Void)
00159 {
00160         next_slot = output_buf = Alloc(MAX_OUTPUT_SIZE);
00161         memset(output_buf, 0, MAX_OUTPUT_SIZE);
00162         }
00163 
00164  static char *
00165 #ifdef KR_headers
00166 adjust_pointer_in_string(pointer)
00167         register char *pointer;
00168 #else
00169 adjust_pointer_in_string(register char *pointer)
00170 #endif
00171 {
00172         register char *s, *s1, *se, *s0;
00173 
00174         /* arrange not to break \002 */
00175         s1 = string_start ? string_start : output_buf;
00176         for(s = s1; s < pointer; s++) {
00177                 s0 = s1;
00178                 s1 = s;
00179                 if (*s == '\\') {
00180                         se = s++ + 4;
00181                         if (se > pointer)
00182                                 break;
00183                         if (*s < '0' || *s > '7')
00184                                 continue;
00185                         while(++s < se)
00186                                 if (*s < '0' || *s > '7')
00187                                         break;
00188                         --s;
00189                         }
00190                 }
00191         return s0 - 1;
00192         }
00193 
00194 /* ANSI says strcpy's behavior is undefined for overlapping args,
00195  * so we roll our own fwd_strcpy: */
00196 
00197  static void
00198 #ifdef KR_headers
00199 fwd_strcpy(t, s)
00200         register char *t;
00201         register char *s;
00202 #else
00203 fwd_strcpy(register char *t, register char *s)
00204 #endif
00205 { while(*t++ = *s++); }
00206 
00207 /* isident -- true iff character could belong to a unit.  C allows
00208    letters, numbers and underscores in identifiers.  This also doubles as
00209    a check for numeric constants, since we include the decimal point and
00210    minus sign.  The minus has to be here, since the constant "10e-2"
00211    cannot be broken up.  The '.' also prevents structure references from
00212    being broken, which is a quite acceptable side effect */
00213 
00214 #define isident(x) (Tr[x] & 1)
00215 #define isntident(x) (!Tr[x])
00216 
00217   static void
00218 #ifdef KR_headers
00219  ind_printf (use_indent, fp, a, b, c, d, e, f, g)
00220   int use_indent;
00221   FILE *fp;
00222   char *a;
00223   long b, c, d, e, f, g;
00224 #else
00225  ind_printf (int use_indent, FILE *fp, char *a, va_list ap)
00226 #endif
00227 {
00228     extern int max_line_len;
00229     extern FILEP c_file;
00230     extern char tr_tab[];       /* in output.c */
00231     register char *Tr = tr_tab;
00232     int ch, inc, ind;
00233     static int extra_indent, last_indent, set_cursor = 1;
00234 
00235     cursor_pos += indent - last_indent;
00236     last_indent = indent;
00237     SPRINTF (next_slot, a, b, c, d, e, f, g);
00238 
00239     if (fp != c_file) {
00240         fprintf (fp,"%s", next_slot);
00241         return;
00242     } /* if fp != c_file */
00243 
00244     do {
00245         char *pointer;
00246 
00247 /* The   for   loop will parse one output line */
00248 
00249         if (set_cursor) {
00250                 ind = indent <= MAX_INDENT
00251                         ? indent
00252                         : MIN_INDENT + indent % (MAX_INDENT - MIN_INDENT);
00253                 cursor_pos = ind + extra_indent;
00254                 set_cursor = 0;
00255                 }
00256         if (in_comment)
00257                 for (pointer = next_slot; *pointer && *pointer != '\n' &&
00258                                 cursor_pos <= max_line_len; pointer++)
00259                         cursor_pos++;
00260         else
00261           for (pointer = next_slot; *pointer && *pointer != '\n' &&
00262                 cursor_pos <= max_line_len; pointer++) {
00263 
00264             /* Update state variables here */
00265 
00266             if (In_string) {
00267                 switch(*pointer) {
00268                         case '\\':
00269                                 if (++cursor_pos > max_line_len) {
00270                                         cursor_pos -= 2;
00271                                         --pointer;
00272                                         goto overflow;
00273                                         }
00274                                 ++pointer;
00275                                 break;
00276                         case '"':
00277                                 In_string = 0;
00278                                 word_start = 0;
00279                         }
00280                 }
00281             else switch (*pointer) {
00282                 case '"':
00283                         if (cursor_pos + 5 > max_line_len) {
00284                                 word_start = 0;
00285                                 --pointer;
00286                                 goto overflow;
00287                                 }
00288                         In_string = 1;
00289                         string_start = word_start = pointer;
00290                         break;
00291                 case '\'':
00292                         if (pointer[1] == '\\')
00293                                 if ((ch = pointer[2]) >= '0' && ch <= '7')
00294                                         for(inc = 3; pointer[inc] != '\''
00295                                                 && ++inc < 5;);
00296                                 else
00297                                         inc = 3;
00298                         else
00299                                 inc = 2;
00300                         /*debug*/ if (pointer[inc] != '\'')
00301                         /*debug*/  fatalstr("Bad character constant %.10s",
00302                                         pointer);
00303                         if ((cursor_pos += inc) > max_line_len) {
00304                                 cursor_pos -= inc;
00305                                 word_start = 0;
00306                                 --pointer;
00307                                 goto overflow;
00308                                 }
00309                         word_start = pointer;
00310                         pointer += inc;
00311                         break;
00312                 case '\t':
00313                     cursor_pos = 8 * ((cursor_pos + 8) / 8) - 1;
00314                     break;
00315                 default: {
00316 
00317 /* HACK  Assumes that all characters in an atomic C token will be written
00318    at the same time.  Must check for tokens first, since '-' is considered
00319    part of an identifier; checking isident first would mean breaking up "->" */
00320 
00321                     if (word_start) {
00322                         if (isntident(*(unsigned char *)pointer))
00323                                 word_start = NULL;
00324                         }
00325                     else if (isident(*(unsigned char *)pointer))
00326                         word_start = pointer;
00327                     break;
00328                 } /* default */
00329             } /* switch */
00330             cursor_pos++;
00331         } /* for pointer = next_slot */
00332  overflow:
00333         if (*pointer == '\0') {
00334 
00335 /* The output line is not complete, so break out and don't output
00336    anything.  The current line fragment will be stored in the buffer */
00337 
00338             next_slot = pointer;
00339             break;
00340         } else {
00341             char last_char;
00342             int in_string0 = In_string;
00343 
00344 /* If the line was too long, move   pointer   back to the character before
00345    the current word.  This allows line breaking on word boundaries.  Make
00346    sure that 80 character comment lines get broken up somehow.  We assume
00347    that any non-string 80 character identifier must be in a comment.
00348 */
00349 
00350             if (*pointer == '\n')
00351                 in_define = 0;
00352             else if (word_start && word_start > output_buf)
00353                 if (In_string)
00354                         if (string_start && pointer - string_start < 5)
00355                                 pointer = string_start - 1;
00356                         else {
00357                                 pointer = adjust_pointer_in_string(pointer);
00358                                 string_start = 0;
00359                                 }
00360                 else if (word_start == string_start
00361                                 && pointer - string_start >= 5) {
00362                         pointer = adjust_pointer_in_string(next_slot);
00363                         In_string = 1;
00364                         string_start = 0;
00365                         }
00366                 else
00367                         pointer = word_start - 1;
00368             else if (cursor_pos > max_line_len) {
00369 #ifndef ANSI_Libraries
00370                 extern char *strchr();
00371 #endif
00372                 if (In_string) {
00373                         pointer = adjust_pointer_in_string(pointer);
00374                         if (string_start && pointer > string_start)
00375                                 string_start = 0;
00376                         }
00377                 else if (strchr("&*+-/<=>|", *pointer)
00378                         && strchr("!%&*+-/<=>^|", pointer[-1])) {
00379                         pointer -= 2;
00380                         if (strchr("<>", *pointer)) /* <<=, >>= */
00381                                 pointer--;
00382                         }
00383                 else {
00384                         if (word_start)
00385                                 while(isident(*(unsigned char *)pointer))
00386                                         pointer++;
00387                         pointer--;
00388                         }
00389                 }
00390             last_char = *pointer;
00391             write_indent(fp, use_indent, extra_indent, output_buf, pointer);
00392             next_slot = output_buf;
00393             if (In_string && !string_start && Ansi == 1 && last_char != '\n')
00394                 *next_slot++ = '"';
00395             fwd_strcpy(next_slot, pointer + 1);
00396 
00397 /* insert a line break */
00398 
00399             if (last_char == '\n') {
00400                 if (In_string)
00401                         last_was_newline = 0;
00402                 else {
00403                         last_was_newline = 1;
00404                         extra_indent = 0;
00405                         sharp_line = gflag1;
00406                         }
00407                 }
00408             else {
00409                 extra_indent = TOO_LONG_INDENT;
00410                 if (In_string && !string_start) {
00411                         if (Ansi == 1) {
00412                                 fprintf(fp, gflag1 ? "\"\\\n" : "\"\n");
00413                                 use_indent = 1;
00414                                 last_was_newline = 1;
00415                                 }
00416                         else {
00417                                 fprintf(fp, "\\\n");
00418                                 last_was_newline = 0;
00419                                 }
00420                         In_string = in_string0;
00421                         }
00422                 else {
00423                         if (in_define/* | gflag1*/)
00424                                 putc('\\', fp);
00425                         putc ('\n', fp);
00426                         last_was_newline = 1;
00427                         }
00428             } /* if *pointer != '\n' */
00429 
00430             if (In_string && Ansi != 1 && !string_start)
00431                 cursor_pos = 0;
00432             else
00433                 set_cursor = 1;
00434 
00435             string_start = word_start = NULL;
00436 
00437         } /* else */
00438 
00439     } while (*next_slot);
00440 
00441 } /* ind_printf */
 

Powered by Plone

This site conforms to the following standards: