00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
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         } 
00084 
00085         while (tab-- > 0)
00086             putc (' ', fp);
00087     } 
00088 
00089     while (start <= end)
00090         putc (*start++, fp);
00091 } 
00092 
00093 #ifdef KR_headers
00094 
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 } 
00103 
00104 
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 } 
00113 #define SPRINTF(x,a,b,c,d,e,f,g) sprintf(x,a,b,c,d,e,f,g)
00114 
00115 #else 
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                 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
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         
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 
00195 
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 
00208 
00209 
00210 
00211 
00212 
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[];       
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     } 
00243 
00244     do {
00245         char *pointer;
00246 
00247 
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             
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                          if (pointer[inc] != '\'')
00301                           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 
00318 
00319 
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                 } 
00329             } 
00330             cursor_pos++;
00331         } 
00332  overflow:
00333         if (*pointer == '\0') {
00334 
00335 
00336 
00337 
00338             next_slot = pointer;
00339             break;
00340         } else {
00341             char last_char;
00342             int in_string0 = In_string;
00343 
00344 
00345 
00346 
00347 
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 
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)
00424                                 putc('\\', fp);
00425                         putc ('\n', fp);
00426                         last_was_newline = 1;
00427                         }
00428             } 
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         } 
00438 
00439     } while (*next_slot);
00440 
00441 }