LINUX.ORG.RU

История изменений

Исправление firkax, (текущая версия) :

Вот тебе готовый инструмент.

По хорошему надо ещё доработать правильную обработку EINTR и ошибок и динамический размер буфера под строку, но вообще будет работать и так в 99.999% случаев. Сейчас при обнаружении строки длиннее MAX_LINE_LEN символов с //-комментарием результат будет молча некорректный (если без комментария - всё норм). А также при столкновении с например ошибкой чтения с диска прога не выдаст никаких варнингов а просто сделает вид что на этом месте закончился входной файл.

#include <stdio.h>
#include <string.h>
#include <assert.h>

static void handle_line(char *b, char const *eoln, char const *def_eoln);
int main(void) {
#define MAX_LINE_LEN 100000
  static char b[MAX_LINE_LEN];

  char * p;
  char const *eoln, *def_eoln;
  def_eoln = "\n";
  while(fgets(b,sizeof(b),stdin)) {
    p = strchr(b,'\n');
    if(p) {
      assert(!p[1]);
      if(p!=b && *(p-1)=='\r') { eoln = "\r\n"; *(p-1) = 0; }
      else { eoln = "\n"; *p = 0; }
      def_eoln = eoln;
    } else eoln = "";
    handle_line(b, eoln, def_eoln);
  }
  return 0;
}

static void handle_line(char *b, char const *eoln, char const *def_eoln) {
  size_t p, plen;
  char c, q;
  for(p=0; (c=b[p])==' ' || c=='\t'; p++);
  plen = p;
  q = 0;
  while(c = b[p]) {
    if(q) {
      p++;
      if(c==q) q=0;
      else if(c=='\\') { if(b[p]) p++; }
      continue;
    }
    if(c=='\'' || c=='"') { q=c; p++; continue; }
    if(c!='/' || b[p+1]!='/') { p++; continue; }
    if(plen) fwrite(b, 1, plen, stdout);
    fputs(b+p, stdout);
    fputs(def_eoln, stdout);
    while(p && (b[p-1]==' ' || b[p-1]=='\t')) p--;
    if(p) { fwrite(b, 1, p, stdout); fputs(eoln, stdout); }
    return;
  }
  fputs(b, stdout); fputs(eoln, stdout);
}

Исправление firkax, :

Вот тебе готовый инструмент.

По хорошему надо ещё доработать правильную обработку EINTR и ошибок и динамический размер буфера под строку, но вообще будет работать и так в 99.999% случаев.

#include <stdio.h>
#include <string.h>
#include <assert.h>

static void handle_line(char *b, char const *eoln, char const *def_eoln);
int main(void) {
#define MAX_LINE_LEN 100000
  static char b[MAX_LINE_LEN];

  char * p;
  char const *eoln, *def_eoln;
  def_eoln = "\n";
  while(fgets(b,sizeof(b),stdin)) {
    p = strchr(b,'\n');
    if(p) {
      assert(!p[1]);
      if(p!=b && *(p-1)=='\r') { eoln = "\r\n"; *(p-1) = 0; }
      else { eoln = "\n"; *p = 0; }
      def_eoln = eoln;
    } else eoln = "";
    handle_line(b, eoln, def_eoln);
  }
  return 0;
}

static void handle_line(char *b, char const *eoln, char const *def_eoln) {
  size_t p, plen;
  char c, q;
  for(p=0; (c=b[p])==' ' || c=='\t'; p++);
  plen = p;
  q = 0;
  while(c = b[p]) {
    if(q) {
      p++;
      if(c==q) q=0;
      else if(c=='\\') { if(b[p]) p++; }
      continue;
    }
    if(c=='\'' || c=='"') { q=c; p++; continue; }
    if(c!='/' || b[p+1]!='/') { p++; continue; }
    if(plen) fwrite(b, 1, plen, stdout);
    fputs(b+p, stdout);
    fputs(def_eoln, stdout);
    while(p && (b[p-1]==' ' || b[p-1]=='\t')) p--;
    if(p) { fwrite(b, 1, p, stdout); fputs(eoln, stdout); }
    return;
  }
  fputs(b, stdout); fputs(eoln, stdout);
}

Исходная версия firkax, :

Вот тебе готовый инструмент.

По хорошему надо ещё доработать правильную обработку EINTR и ошибок и динамический размер буфера под строку, но вообще будет работать и так в 99.999% случаев.

#include <stdio.h>
#include <assert.h>

static void handle_line(char *b, char const *eoln, char const *def_eoln);
int main(void) {
#define MAX_LINE_LEN 100000
  static char b[MAX_LINE_LEN];

  char * p;
  char const *eoln, *def_eoln;
  def_eoln = "\n";
  while(fgets(b,sizeof(b),stdin)) {
    p = strchr(b,'\n');
    if(p) {
      assert(!p[1]);
      if(p!=b && *(p-1)=='\r') { eoln = "\r\n"; *(p-1) = 0; }
      else { eoln = "\n"; *p = 0; }
      def_eoln = eoln;
    } else eoln = "";
    handle_line(b, eoln, def_eoln);
  }
  return 0;
}

static void handle_line(char *b, char const *eoln, char const *def_eoln) {
  size_t p, plen;
  char c, q;
  for(p=0; (c=b[p])==' ' || c=='\t'); p++);
  plen = p;
  q = 0;
  while(c = b[p]) {
    if(q) {
      p++;
      if(c==q) q=0;
      else if(c=='\\') { if(b[p]) p++; }
      continue;
    }
    if(c=='\'' || c=='"') { q=c; p++; continue; }
    if(c!='/' || b[p+1]!='/') { p++; continue; }
    if(plen) fwrite(b, 1, plen, stdout);
    fputs(b+p, stdout);
    fputs(def_eoln, stdout);
    while(p && (b[p-1]==' ' || b[p-1]=='\t')) p--;
    if(p) { fwrite(b, 1, p, stdout); fputs(eoln, stdout); }
    return;
  }
  fputs(b, stdout);
}