Justin808
Justin808

Reputation: 21512

How do I keep all formatting (whitespace) when using bash?

I need to add 3 lines into a file via a bash script; sed and awk are not and can not be installed. I have the following script insert the lines, but via the vertue of bash all formatting in the file is lost. I suspect its mangling the file in other ways as well as I get additional errors when I try to compile using the resulting, modified, file.

c=0
while read line
do
 if [ "$c" -eq 99 ]; then
  echo -e "// Added by build.sh\n#define PROGMEM\n#define prog_char\n\n$line"
 else
  echo "$line"
 fi
((c=c+1))
done < libdefs.h >> libdefs.h.new

Updated script:

This preserves the formatting, and adds the lines, but mangles the file somehow. If I add the 3 lines manually and compile the app it works, if I use the script I get all kinds of errors.

c=0
while IFS= read line
do
 if [ "$c" -eq 99 ]; then
  echo "// Added by build.sh"
  echo "#define PROGMEM"
  echo "#define prog_char"
  echo ""
 fi
 echo "$line"
 ((c=c+1))
done < libdefs.h >> libdefs.h.new

The first being libdefs.h:363:2: error: expected identifier or '(' before numeric constant. so it looks like parens are being messed with.

Diff:

--- libdefs.h.old   2011-10-01 13:46:34.000000000 -1000
+++ libdefs.h   2012-03-02 22:00:16.000000000 -1000
@@ -97,6 +97,10 @@
    #include <avr/interrupt.h>
 #endif

+// Added by build.sh
+#define PROGMEM
+#define prog_char
+
 // create a type for boolean
 typedef int8_t boolean;

@@ -351,35 +355,35 @@
 typedef uint16_t TIMER_MODES;

 // The set of PWM modes
-#define PWM_MODES ((TIMER_MODES)( \
-   BV(TIMER_MODE_PWM8_PHASE_CORRECT) | \
-   BV(TIMER_MODE_PWM9_PHASE_CORRECT) | \
-   BV(TIMER_MODE_PWM10_PHASE_CORRECT) | \
-   BV(TIMER_MODE_PWM8_FAST) | \
-   BV(TIMER_MODE_PWM9_FAST) | \
-   BV(TIMER_MODE_PWM10_FAST) | \
-   BV(TIMER_MODE_PWM_PHASE_FREQ_ICR) | \
-   BV(TIMER_MODE_PWM_PHASE_FREQ_OCR) | \
-   BV(TIMER_MODE_PWM_PHASE_CORRECT_ICR) | \
-   BV(TIMER_MODE_PWM_PHASE_CORRECT_OCR) | \
-   BV(TIMER_MODE_PWM_FAST_ICR) | \
-   BV(TIMER_MODE_PWM_FAST_OCR) \
+#define PWM_MODES ((TIMER_MODES)( 
+   BV(TIMER_MODE_PWM8_PHASE_CORRECT) | 
+   BV(TIMER_MODE_PWM9_PHASE_CORRECT) | 
+   BV(TIMER_MODE_PWM10_PHASE_CORRECT) | 
+   BV(TIMER_MODE_PWM8_FAST) | 
+   BV(TIMER_MODE_PWM9_FAST) | 
+   BV(TIMER_MODE_PWM10_FAST) | 
+   BV(TIMER_MODE_PWM_PHASE_FREQ_ICR) | 
+   BV(TIMER_MODE_PWM_PHASE_FREQ_OCR) | 
+   BV(TIMER_MODE_PWM_PHASE_CORRECT_ICR) | 
+   BV(TIMER_MODE_PWM_PHASE_CORRECT_OCR) | 
+   BV(TIMER_MODE_PWM_FAST_ICR) | 
+   BV(TIMER_MODE_PWM_FAST_OCR) 
 ))

 // The set of ICR modes
-#define ICR_MODES ((TIMER_MODES)( \
-   BV(TIMER_MODE_PWM_PHASE_FREQ_ICR) | \
-   BV(TIMER_MODE_PWM_PHASE_CORRECT_ICR) | \
-   BV(TIMER_MODE_CTC_ICR) | \
-   BV(TIMER_MODE_PWM_FAST_ICR)  \
+#define ICR_MODES ((TIMER_MODES)( 
+   BV(TIMER_MODE_PWM_PHASE_FREQ_ICR) | 
+   BV(TIMER_MODE_PWM_PHASE_CORRECT_ICR) | 
+   BV(TIMER_MODE_CTC_ICR) | 
+   BV(TIMER_MODE_PWM_FAST_ICR)  
 ))

 // The set of OCR modes
-#define OCR_MODES ((TIMER_MODES)( \
-   BV(TIMER_MODE_CTC_OCR) | \
-   BV(TIMER_MODE_PWM_PHASE_FREQ_OCR) | \
-   BV(TIMER_MODE_PWM_PHASE_CORRECT_OCR) | \
-   BV(TIMER_MODE_PWM_FAST_OCR)  \
+#define OCR_MODES ((TIMER_MODES)( 
+   BV(TIMER_MODE_CTC_OCR) | 
+   BV(TIMER_MODE_PWM_PHASE_FREQ_OCR) | 
+   BV(TIMER_MODE_PWM_PHASE_CORRECT_OCR) | 
+   BV(TIMER_MODE_PWM_FAST_OCR)  
 ))

 #define modeIsPWM(mode) ( ((TIMER_MODES)(BV(mode))) & PWM_MODES)
@@ -389,29 +393,29 @@
 #define TIMER_NO_MODES 0

 // Define bits if all modes are supported
-#define TIMER_ALL_MODES ((TIMER_MODES)( \
-   BV(TIMER_MODE_NORMAL)|\
-   BV(TIMER_MODE_PWM8_PHASE_CORRECT)|\
-   BV(TIMER_MODE_PWM9_PHASE_CORRECT)|\
-   BV(TIMER_MODE_PWM10_PHASE_CORRECT)|\
-   BV(TIMER_MODE_CTC_OCR)|\
-   BV(TIMER_MODE_PWM8_FAST)|\
-   BV(TIMER_MODE_PWM9_FAST)|\
-   BV(TIMER_MODE_PWM10_FAST)|\
-   BV(TIMER_MODE_PWM_PHASE_FREQ_ICR)|\
-   BV(TIMER_MODE_PWM_PHASE_FREQ_OCR)|\
-   BV(TIMER_MODE_PWM_PHASE_CORRECT_ICR)|\
-   BV(TIMER_MODE_PWM_PHASE_CORRECT_OCR)|\
-   BV(TIMER_MODE_CTC_ICR)|\
-   BV(TIMER_MODE_PWM_FAST_ICR)|\
-   BV(TIMER_MODE_PWM_FAST_OCR)\
+#define TIMER_ALL_MODES ((TIMER_MODES)( 
+   BV(TIMER_MODE_NORMAL)|
+   BV(TIMER_MODE_PWM8_PHASE_CORRECT)|
+   BV(TIMER_MODE_PWM9_PHASE_CORRECT)|
+   BV(TIMER_MODE_PWM10_PHASE_CORRECT)|
+   BV(TIMER_MODE_CTC_OCR)|
+   BV(TIMER_MODE_PWM8_FAST)|
+   BV(TIMER_MODE_PWM9_FAST)|
+   BV(TIMER_MODE_PWM10_FAST)|
+   BV(TIMER_MODE_PWM_PHASE_FREQ_ICR)|
+   BV(TIMER_MODE_PWM_PHASE_FREQ_OCR)|
+   BV(TIMER_MODE_PWM_PHASE_CORRECT_ICR)|
+   BV(TIMER_MODE_PWM_PHASE_CORRECT_OCR)|
+   BV(TIMER_MODE_CTC_ICR)|
+   BV(TIMER_MODE_PWM_FAST_ICR)|
+   BV(TIMER_MODE_PWM_FAST_OCR)
 ))

 // Define bits for less capable timers
-#define TIMER_3BIT_MODES (BV(TIMER_MODE_NORMAL)| BV(TIMER_MODE_PWM8_PHASE_CORRECT)|BV(TIMER_MODE_CTC_OCR)| \
+#define TIMER_3BIT_MODES (BV(TIMER_MODE_NORMAL)| BV(TIMER_MODE_PWM8_PHASE_CORRECT)|BV(TIMER_MODE_CTC_OCR)| 
        BV(TIMER_MODE_PWM8_FAST)|BV(TIMER_MODE_PWM_PHASE_CORRECT_OCR)|BV(TIMER_MODE_PWM_FAST_OCR))

-#define TIMER_2BIT_MODES (BV(TIMER_MODE_NORMAL)| BV(TIMER_MODE_PWM8_PHASE_CORRECT)|BV(TIMER_MODE_CTC_OCR)| \
+#define TIMER_2BIT_MODES (BV(TIMER_MODE_NORMAL)| BV(TIMER_MODE_PWM8_PHASE_CORRECT)|BV(TIMER_MODE_CTC_OCR)| 
        BV(TIMER_MODE_PWM8_FAST))


@@ -444,11 +448,11 @@


 #define MAKE_TIMER_COMPARE_DATA() {0,null/*,0*/}
-#define MAKE_TIMER_COMPARE(data,timer,port,mask,threshold, intport,intmask, comport,combit,pwm) \
-   {&data,timer, {_SFR_MEM_ADDR(port),BV(mask)},_SFR_MEM_ADDR(threshold), \
-   {_SFR_MEM_ADDR(intport),BV(intmask)}, \
-   {_SFR_MEM_ADDR(comport),combit}, \
-   pwm \
+#define MAKE_TIMER_COMPARE(data,timer,port,mask,threshold, intport,intmask, comport,combit,pwm) 
+   {&data,timer, {_SFR_MEM_ADDR(port),BV(mask)},_SFR_MEM_ADDR(threshold), 
+   {_SFR_MEM_ADDR(intport),BV(intmask)}, 
+   {_SFR_MEM_ADDR(comport),combit}, 
+   pwm 
    }

 /**
@@ -493,27 +497,27 @@
 } TimerData;

 #define MAKE_TIMER_DATA(prescale) {prescale,/*0,*/null,null,null,null,TIMER_MODE_NORMAL}
-#define MAKE_TIMER(data, counter,prescaler,sixteenBit,rtc,modes, \
-   wgm0port, wgm0mask, wgm1port, wgm1mask, wgm2port, wgm2mask, wgm3port, wgm3mask, \
-    compares,ovrintport,ovrintmask,ovrreqport,ovrreqmask,icr, \
-    capintport,capintmask,capreqport,capreqmask, capedgeport,capedgemask,\
-    incapin \
-   ) \
-   {&data, _SFR_MEM_ADDR(counter), _SFR_MEM_ADDR(prescaler), sixteenBit, rtc, sizeof(compares)/sizeof(TimerCompare),modes, \
-       { \
-           {_SFR_MEM_ADDR(wgm0port),BV(wgm0mask)}, \
-           {_SFR_MEM_ADDR(wgm1port),BV(wgm1mask)}, \
-           {_SFR_MEM_ADDR(wgm2port),BV(wgm2mask)}, \
-           {_SFR_MEM_ADDR(wgm3port),BV(wgm3mask)}  \
-       },\
-       compares,\
-   {_SFR_MEM_ADDR(ovrintport),BV(ovrintmask)},\
-   {_SFR_MEM_ADDR(ovrreqport),BV(ovrreqmask)}, \
-   _SFR_MEM_ADDR(icr),\
-   {_SFR_MEM_ADDR(capintport),BV(capintmask)},\
-   {_SFR_MEM_ADDR(capreqport),BV(capreqmask)}, \
-   {_SFR_MEM_ADDR(capedgeport),BV(capedgemask)}, \
-   incapin \
+#define MAKE_TIMER(data, counter,prescaler,sixteenBit,rtc,modes, 
+   wgm0port, wgm0mask, wgm1port, wgm1mask, wgm2port, wgm2mask, wgm3port, wgm3mask, 
+    compares,ovrintport,ovrintmask,ovrreqport,ovrreqmask,icr, 
+    capintport,capintmask,capreqport,capreqmask, capedgeport,capedgemask,
+    incapin 
+   ) 
+   {&data, _SFR_MEM_ADDR(counter), _SFR_MEM_ADDR(prescaler), sixteenBit, rtc, sizeof(compares)/sizeof(TimerCompare),modes, 
+       { 
+           {_SFR_MEM_ADDR(wgm0port),BV(wgm0mask)}, 
+           {_SFR_MEM_ADDR(wgm1port),BV(wgm1mask)}, 
+           {_SFR_MEM_ADDR(wgm2port),BV(wgm2mask)}, 
+           {_SFR_MEM_ADDR(wgm3port),BV(wgm3mask)}  
+       },
+       compares,
+   {_SFR_MEM_ADDR(ovrintport),BV(ovrintmask)},
+   {_SFR_MEM_ADDR(ovrreqport),BV(ovrreqmask)}, 
+   _SFR_MEM_ADDR(icr),
+   {_SFR_MEM_ADDR(capintport),BV(capintmask)},
+   {_SFR_MEM_ADDR(capreqport),BV(capreqmask)}, 
+   {_SFR_MEM_ADDR(capedgeport),BV(capedgemask)}, 
+   incapin 
    }

 // Define the signature of code that is the destination of an rprintf output

Upvotes: 1

Views: 848

Answers (2)

potong
potong

Reputation: 58361

This might work for you:

OIFS=$IFS; IFS=$'\n'; a=($(<libdefs.h)); IFS=$OIFS
a[98]=$'// Added by build.sh\n#define PROGMEM\n#define prog_char\n'${a[98]} 
printf "%s\n" "${a[@]}" >libdefs.h.new

or this:

{ head -n98 libdefs.h;
printf "// Added by build.sh\n#define PROGMEM\n#define prog_char\n"
tail -n+99 libdefs.h; } >libdefs.h.new

Upvotes: 0

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798526

You need to tell read to not split words (or rather, make it unable to split words).

while IFS= read line

Also, echo -e on $line is going to do bad things. Always print $line, and conditionally print the other stuff.

EDIT:

Aha. You'll also need to use read -r to prevent it from killing your backslashes.

Upvotes: 4

Related Questions