14616d0f9Sopenharmony_ci# Convert tzdata source into vanguard or rearguard form.
24616d0f9Sopenharmony_ci
34616d0f9Sopenharmony_ci# Contributed by Paul Eggert.  This file is in the public domain.
44616d0f9Sopenharmony_ci
54616d0f9Sopenharmony_ci# This is not a general-purpose converter; it is designed for current tzdata.
64616d0f9Sopenharmony_ci# It just converts from current source to main, vanguard, and rearguard forms.
74616d0f9Sopenharmony_ci# Although it might be nice for it to be idempotent, or to be useful
84616d0f9Sopenharmony_ci# for converting back and forth between vanguard and rearguard formats,
94616d0f9Sopenharmony_ci# it does not do these nonessential tasks now.
104616d0f9Sopenharmony_ci#
114616d0f9Sopenharmony_ci# Although main and vanguard forms are currently equivalent,
124616d0f9Sopenharmony_ci# this need not always be the case.  When the two forms differ,
134616d0f9Sopenharmony_ci# this script can convert either from main to vanguard form (needed then),
144616d0f9Sopenharmony_ci# or from vanguard to main form (this conversion would be needed later,
154616d0f9Sopenharmony_ci# after main became rearguard and vanguard became main).
164616d0f9Sopenharmony_ci# There is no need to convert rearguard to other forms.
174616d0f9Sopenharmony_ci#
184616d0f9Sopenharmony_ci# When converting to vanguard form, the output can use the line
194616d0f9Sopenharmony_ci# "Zone GMT 0 - GMT" which TZUpdater 2.3.2 mistakenly rejects.
204616d0f9Sopenharmony_ci#
214616d0f9Sopenharmony_ci# When converting to vanguard form, the output can use negative SAVE
224616d0f9Sopenharmony_ci# values.
234616d0f9Sopenharmony_ci#
244616d0f9Sopenharmony_ci# When converting to rearguard form, the output uses only nonnegative
254616d0f9Sopenharmony_ci# SAVE values.  The idea is for the output data to simulate the behavior
264616d0f9Sopenharmony_ci# of the input data as best it can within the constraints of the
274616d0f9Sopenharmony_ci# rearguard format.
284616d0f9Sopenharmony_ci
294616d0f9Sopenharmony_ci# Given a FIELD like "-0:30", return a minute count like -30.
304616d0f9Sopenharmony_cifunction get_minutes(field, \
314616d0f9Sopenharmony_ci		     sign, hours, minutes)
324616d0f9Sopenharmony_ci{
334616d0f9Sopenharmony_ci  sign = field ~ /^-/ ? -1 : 1
344616d0f9Sopenharmony_ci  hours = +field
354616d0f9Sopenharmony_ci  if (field ~ /:/) {
364616d0f9Sopenharmony_ci    minutes = field
374616d0f9Sopenharmony_ci    sub(/[^:]*:/, "", minutes)
384616d0f9Sopenharmony_ci  }
394616d0f9Sopenharmony_ci  return 60 * hours + sign * minutes
404616d0f9Sopenharmony_ci}
414616d0f9Sopenharmony_ci
424616d0f9Sopenharmony_ci# Given an OFFSET, which is a minute count like 300 or 330,
434616d0f9Sopenharmony_ci# return a %z-style abbreviation like "+05" or "+0530".
444616d0f9Sopenharmony_cifunction offset_abbr(offset, \
454616d0f9Sopenharmony_ci		     hours, minutes, sign)
464616d0f9Sopenharmony_ci{
474616d0f9Sopenharmony_ci  hours = int(offset / 60)
484616d0f9Sopenharmony_ci  minutes = offset % 60
494616d0f9Sopenharmony_ci  if (minutes) {
504616d0f9Sopenharmony_ci    return sprintf("%+.4d", hours * 100 + minutes);
514616d0f9Sopenharmony_ci  } else {
524616d0f9Sopenharmony_ci    return sprintf("%+.2d", hours)
534616d0f9Sopenharmony_ci  }
544616d0f9Sopenharmony_ci}
554616d0f9Sopenharmony_ci
564616d0f9Sopenharmony_ci# Round TIMESTAMP (a +-hh:mm:ss.dddd string) to the nearest second.
574616d0f9Sopenharmony_cifunction round_to_second(timestamp, \
584616d0f9Sopenharmony_ci			 hh, mm, ss, seconds, dot_dddd, subseconds)
594616d0f9Sopenharmony_ci{
604616d0f9Sopenharmony_ci  dot_dddd = timestamp
614616d0f9Sopenharmony_ci  if (!sub(/^[+-]?[0-9]+:[0-9]+:[0-9]+\./, ".", dot_dddd))
624616d0f9Sopenharmony_ci    return timestamp
634616d0f9Sopenharmony_ci  hh = mm = ss = timestamp
644616d0f9Sopenharmony_ci  sub(/^[-+]?[0-9]+:[0-9]+:/, "", ss)
654616d0f9Sopenharmony_ci  sub(/^[-+]?[0-9]+:/, "", mm)
664616d0f9Sopenharmony_ci  sub(/^[-+]?/, "", hh)
674616d0f9Sopenharmony_ci  seconds = 3600 * hh + 60 * mm + ss
684616d0f9Sopenharmony_ci  subseconds = +dot_dddd
694616d0f9Sopenharmony_ci  seconds += 0.5 < subseconds || ((subseconds == 0.5) && (seconds % 2));
704616d0f9Sopenharmony_ci  return sprintf("%s%d:%.2d:%.2d", timestamp ~ /^-/ ? "-" : "", \
714616d0f9Sopenharmony_ci		 seconds / 3600, seconds / 60 % 60, seconds % 60)
724616d0f9Sopenharmony_ci}
734616d0f9Sopenharmony_ci
744616d0f9Sopenharmony_ciBEGIN {
754616d0f9Sopenharmony_ci  dataform_type["vanguard"] = 1
764616d0f9Sopenharmony_ci  dataform_type["main"] = 1
774616d0f9Sopenharmony_ci  dataform_type["rearguard"] = 1
784616d0f9Sopenharmony_ci
794616d0f9Sopenharmony_ci  if (PACKRATLIST) {
804616d0f9Sopenharmony_ci    while (getline <PACKRATLIST) {
814616d0f9Sopenharmony_ci      if ($0 ~ /^#/) continue
824616d0f9Sopenharmony_ci      packratlist[$3] = 1
834616d0f9Sopenharmony_ci    }
844616d0f9Sopenharmony_ci  }
854616d0f9Sopenharmony_ci
864616d0f9Sopenharmony_ci  # The command line should set DATAFORM.
874616d0f9Sopenharmony_ci  if (!dataform_type[DATAFORM]) exit 1
884616d0f9Sopenharmony_ci}
894616d0f9Sopenharmony_ci
904616d0f9Sopenharmony_ci$1 == "#PACKRATLIST" && $2 == PACKRATLIST {
914616d0f9Sopenharmony_ci  sub(/^#PACKRATLIST[\t ]+[^\t ]+[\t ]+/, "")
924616d0f9Sopenharmony_ci}
934616d0f9Sopenharmony_ci
944616d0f9Sopenharmony_ci/^Zone/ { zone = $2 }
954616d0f9Sopenharmony_ci
964616d0f9Sopenharmony_ciDATAFORM != "main" {
974616d0f9Sopenharmony_ci  in_comment = $0 ~ /^#/
984616d0f9Sopenharmony_ci  uncomment = comment_out = 0
994616d0f9Sopenharmony_ci
1004616d0f9Sopenharmony_ci  # If this line should differ due to Czechoslovakia using negative SAVE values,
1014616d0f9Sopenharmony_ci  # uncomment the desired version and comment out the undesired one.
1024616d0f9Sopenharmony_ci  if (zone == "Europe/Prague" && $0 ~ /^#?[\t ]+[01]:00[\t ]/ \
1034616d0f9Sopenharmony_ci      && $0 ~ /1947 Feb 23/) {
1044616d0f9Sopenharmony_ci    if (($(in_comment + 2) != "-") == (DATAFORM != "rearguard")) {
1054616d0f9Sopenharmony_ci      uncomment = in_comment
1064616d0f9Sopenharmony_ci    } else {
1074616d0f9Sopenharmony_ci      comment_out = !in_comment
1084616d0f9Sopenharmony_ci    }
1094616d0f9Sopenharmony_ci  }
1104616d0f9Sopenharmony_ci
1114616d0f9Sopenharmony_ci  # If this line should differ due to Ireland using negative SAVE values,
1124616d0f9Sopenharmony_ci  # uncomment the desired version and comment out the undesired one.
1134616d0f9Sopenharmony_ci  Rule_Eire = $0 ~ /^#?Rule[\t ]+Eire[\t ]/
1144616d0f9Sopenharmony_ci  Zone_Dublin_post_1968 \
1154616d0f9Sopenharmony_ci    = (zone == "Europe/Dublin" && $0 ~ /^#?[\t ]+[01]:00[\t ]/ \
1164616d0f9Sopenharmony_ci       && (!$(in_comment + 4) || 1968 < $(in_comment + 4)))
1174616d0f9Sopenharmony_ci  if (Rule_Eire || Zone_Dublin_post_1968) {
1184616d0f9Sopenharmony_ci    if ((Rule_Eire \
1194616d0f9Sopenharmony_ci	 || (Zone_Dublin_post_1968 && $(in_comment + 3) == "IST/GMT"))	\
1204616d0f9Sopenharmony_ci	== (DATAFORM != "rearguard")) {
1214616d0f9Sopenharmony_ci      uncomment = in_comment
1224616d0f9Sopenharmony_ci    } else {
1234616d0f9Sopenharmony_ci      comment_out = !in_comment
1244616d0f9Sopenharmony_ci    }
1254616d0f9Sopenharmony_ci  }
1264616d0f9Sopenharmony_ci
1274616d0f9Sopenharmony_ci  # If this line should differ due to Namibia using negative SAVE values,
1284616d0f9Sopenharmony_ci  # uncomment the desired version and comment out the undesired one.
1294616d0f9Sopenharmony_ci  Rule_Namibia = $0 ~ /^#?Rule[\t ]+Namibia[\t ]/
1304616d0f9Sopenharmony_ci  Zone_using_Namibia_rule \
1314616d0f9Sopenharmony_ci    = (zone == "Africa/Windhoek" && $0 ~ /^#?[\t ]+[12]:00[\t ]/ \
1324616d0f9Sopenharmony_ci       && ($(in_comment + 2) == "Namibia" \
1334616d0f9Sopenharmony_ci	   || ($(in_comment + 2) == "-" && $(in_comment + 3) == "CAT" \
1344616d0f9Sopenharmony_ci	       && ((1994 <= $(in_comment + 4) && $(in_comment + 4) <= 2017) \
1354616d0f9Sopenharmony_ci		   || in_comment + 3 == NF))))
1364616d0f9Sopenharmony_ci  if (Rule_Namibia || Zone_using_Namibia_rule) {
1374616d0f9Sopenharmony_ci    if ((Rule_Namibia \
1384616d0f9Sopenharmony_ci	 ? ($9 ~ /^-/ || ($9 == 0 && $10 == "CAT")) \
1394616d0f9Sopenharmony_ci	 : $(in_comment + 1) == "2:00" && $(in_comment + 2) == "Namibia") \
1404616d0f9Sopenharmony_ci	== (DATAFORM != "rearguard")) {
1414616d0f9Sopenharmony_ci      uncomment = in_comment
1424616d0f9Sopenharmony_ci    } else {
1434616d0f9Sopenharmony_ci      comment_out = !in_comment
1444616d0f9Sopenharmony_ci    }
1454616d0f9Sopenharmony_ci  }
1464616d0f9Sopenharmony_ci
1474616d0f9Sopenharmony_ci  # If this line should differ due to Portugal benefiting from %z if supported,
1484616d0f9Sopenharmony_ci  # uncomment the desired version and comment out the undesired one.
1494616d0f9Sopenharmony_ci  if ($0 ~ /^#?[\t ]+-[12]:00[\t ]+Port[\t ]+[%+-]/) {
1504616d0f9Sopenharmony_ci    if (($0 ~ /%z/) == (DATAFORM == "vanguard")) {
1514616d0f9Sopenharmony_ci      uncomment = in_comment
1524616d0f9Sopenharmony_ci    } else {
1534616d0f9Sopenharmony_ci      comment_out = !in_comment
1544616d0f9Sopenharmony_ci    }
1554616d0f9Sopenharmony_ci  }
1564616d0f9Sopenharmony_ci
1574616d0f9Sopenharmony_ci  # In vanguard form, use the line "Zone GMT 0 - GMT" instead of
1584616d0f9Sopenharmony_ci  # "Zone Etc/GMT 0 - GMT" and adjust Link lines accordingly.
1594616d0f9Sopenharmony_ci  # This works around a bug in TZUpdater 2.3.2.
1604616d0f9Sopenharmony_ci  if (/^#?(Zone|Link)[\t ]+(Etc\/)?GMT[\t ]/) {
1614616d0f9Sopenharmony_ci    if (($2 == "GMT") == (DATAFORM == "vanguard")) {
1624616d0f9Sopenharmony_ci      uncomment = in_comment
1634616d0f9Sopenharmony_ci    } else {
1644616d0f9Sopenharmony_ci      comment_out = !in_comment
1654616d0f9Sopenharmony_ci    }
1664616d0f9Sopenharmony_ci  }
1674616d0f9Sopenharmony_ci
1684616d0f9Sopenharmony_ci  if (uncomment) {
1694616d0f9Sopenharmony_ci    sub(/^#/, "")
1704616d0f9Sopenharmony_ci  }
1714616d0f9Sopenharmony_ci  if (comment_out) {
1724616d0f9Sopenharmony_ci    sub(/^/, "#")
1734616d0f9Sopenharmony_ci  }
1744616d0f9Sopenharmony_ci
1754616d0f9Sopenharmony_ci  # Prefer %z in vanguard form, explicit abbreviations otherwise.
1764616d0f9Sopenharmony_ci  if (DATAFORM == "vanguard") {
1774616d0f9Sopenharmony_ci    sub(/^(Zone[\t ]+[^\t ]+)?[\t ]+[^\t ]+[\t ]+[^\t ]+[\t ]+[-+][^\t ]+/, \
1784616d0f9Sopenharmony_ci	"&CHANGE-TO-%z")
1794616d0f9Sopenharmony_ci    sub(/-00CHANGE-TO-%z/, "-00")
1804616d0f9Sopenharmony_ci    sub(/[-+][^\t ]+CHANGE-TO-/, "")
1814616d0f9Sopenharmony_ci  } else {
1824616d0f9Sopenharmony_ci    if ($0 ~ /^[^#]*%z/) {
1834616d0f9Sopenharmony_ci      stdoff_column = 2 * ($0 ~ /^Zone/) + 1
1844616d0f9Sopenharmony_ci      rules_column = stdoff_column + 1
1854616d0f9Sopenharmony_ci      stdoff = get_minutes($stdoff_column)
1864616d0f9Sopenharmony_ci      rules = $rules_column
1874616d0f9Sopenharmony_ci      stdabbr = offset_abbr(stdoff)
1884616d0f9Sopenharmony_ci      if (rules == "-") {
1894616d0f9Sopenharmony_ci	abbr = stdabbr
1904616d0f9Sopenharmony_ci      } else {
1914616d0f9Sopenharmony_ci	dstabbr_only = rules ~ /^[+0-9-]/
1924616d0f9Sopenharmony_ci	if (dstabbr_only) {
1934616d0f9Sopenharmony_ci	  dstoff = get_minutes(rules)
1944616d0f9Sopenharmony_ci	} else {
1954616d0f9Sopenharmony_ci	  # The DST offset is normally an hour, but there are special cases.
1964616d0f9Sopenharmony_ci	  if (rules == "Morocco" && NF == 3) {
1974616d0f9Sopenharmony_ci	    dstoff = -60
1984616d0f9Sopenharmony_ci	  } else if (rules == "NBorneo") {
1994616d0f9Sopenharmony_ci	    dstoff = 20
2004616d0f9Sopenharmony_ci	  } else if (((rules == "Cook" || rules == "LH") && NF == 3) \
2014616d0f9Sopenharmony_ci		     || (rules == "Uruguay" \
2024616d0f9Sopenharmony_ci			 && $0 ~ /[\t ](1942 Dec 14|1960|1970|1974 Dec 22)$/)) {
2034616d0f9Sopenharmony_ci	    dstoff = 30
2044616d0f9Sopenharmony_ci	  } else if (rules == "Uruguay" && $0 ~ /[\t ]1974 Mar 10$/) {
2054616d0f9Sopenharmony_ci	    dstoff = 90
2064616d0f9Sopenharmony_ci	  } else {
2074616d0f9Sopenharmony_ci	    dstoff = 60
2084616d0f9Sopenharmony_ci	  }
2094616d0f9Sopenharmony_ci	}
2104616d0f9Sopenharmony_ci	dstabbr = offset_abbr(stdoff + dstoff)
2114616d0f9Sopenharmony_ci	if (dstabbr_only) {
2124616d0f9Sopenharmony_ci	  abbr = dstabbr
2134616d0f9Sopenharmony_ci	} else {
2144616d0f9Sopenharmony_ci	  abbr = stdabbr "/" dstabbr
2154616d0f9Sopenharmony_ci	}
2164616d0f9Sopenharmony_ci      }
2174616d0f9Sopenharmony_ci      sub(/%z/, abbr)
2184616d0f9Sopenharmony_ci    }
2194616d0f9Sopenharmony_ci  }
2204616d0f9Sopenharmony_ci
2214616d0f9Sopenharmony_ci  # Normally, prefer whole seconds.  However, prefer subseconds
2224616d0f9Sopenharmony_ci  # if generating vanguard form and the otherwise-undocumented
2234616d0f9Sopenharmony_ci  # VANGUARD_SUBSECONDS environment variable is set.
2244616d0f9Sopenharmony_ci  # This relies on #STDOFF comment lines in the data.
2254616d0f9Sopenharmony_ci  # It is for hypothetical clients that support UT offsets that are
2264616d0f9Sopenharmony_ci  # not integer multiples of one second (e.g., Europe/Lisbon, 1884 to 1912).
2274616d0f9Sopenharmony_ci  # No known clients need this currently, and this experimental
2284616d0f9Sopenharmony_ci  # feature may be changed or withdrawn in future releases.
2294616d0f9Sopenharmony_ci  if ($1 == "#STDOFF") {
2304616d0f9Sopenharmony_ci    stdoff = $2
2314616d0f9Sopenharmony_ci    rounded_stdoff = round_to_second(stdoff)
2324616d0f9Sopenharmony_ci    if (DATAFORM == "vanguard" && ENVIRON["VANGUARD_SUBSECONDS"]) {
2334616d0f9Sopenharmony_ci      stdoff_subst[0] = rounded_stdoff
2344616d0f9Sopenharmony_ci      stdoff_subst[1] = stdoff
2354616d0f9Sopenharmony_ci    } else {
2364616d0f9Sopenharmony_ci      stdoff_subst[0] = stdoff
2374616d0f9Sopenharmony_ci      stdoff_subst[1] = rounded_stdoff
2384616d0f9Sopenharmony_ci    }
2394616d0f9Sopenharmony_ci  } else if (stdoff_subst[0]) {
2404616d0f9Sopenharmony_ci    stdoff_column = 2 * ($0 ~ /^Zone/) + 1
2414616d0f9Sopenharmony_ci    stdoff_column_val = $stdoff_column
2424616d0f9Sopenharmony_ci    if (stdoff_column_val == stdoff_subst[0]) {
2434616d0f9Sopenharmony_ci      sub(stdoff_subst[0], stdoff_subst[1])
2444616d0f9Sopenharmony_ci    } else if (stdoff_column_val != stdoff_subst[1]) {
2454616d0f9Sopenharmony_ci      stdoff_subst[0] = 0
2464616d0f9Sopenharmony_ci    }
2474616d0f9Sopenharmony_ci  }
2484616d0f9Sopenharmony_ci
2494616d0f9Sopenharmony_ci  # In rearguard form, change the Japan rule line with "Sat>=8 25:00"
2504616d0f9Sopenharmony_ci  # to "Sun>=9 1:00", to cater to zic before 2007 and to older Java.
2514616d0f9Sopenharmony_ci  if ($0 ~ /^Rule/ && $2 == "Japan") {
2524616d0f9Sopenharmony_ci    if (DATAFORM == "rearguard") {
2534616d0f9Sopenharmony_ci      if ($7 == "Sat>=8" && $8 == "25:00") {
2544616d0f9Sopenharmony_ci	sub(/Sat>=8/, "Sun>=9")
2554616d0f9Sopenharmony_ci	sub(/25:00/, " 1:00")
2564616d0f9Sopenharmony_ci      }
2574616d0f9Sopenharmony_ci    } else {
2584616d0f9Sopenharmony_ci      if ($7 == "Sun>=9" && $8 == "1:00") {
2594616d0f9Sopenharmony_ci	sub(/Sun>=9/, "Sat>=8")
2604616d0f9Sopenharmony_ci	sub(/ 1:00/, "25:00")
2614616d0f9Sopenharmony_ci      }
2624616d0f9Sopenharmony_ci    }
2634616d0f9Sopenharmony_ci  }
2644616d0f9Sopenharmony_ci
2654616d0f9Sopenharmony_ci  # In rearguard form, change the Morocco lines with negative SAVE values
2664616d0f9Sopenharmony_ci  # to use positive SAVE values.
2674616d0f9Sopenharmony_ci  if ($2 == "Morocco") {
2684616d0f9Sopenharmony_ci    if ($0 ~ /^Rule/) {
2694616d0f9Sopenharmony_ci      if ($4 ~ /^201[78]$/ && $6 == "Oct") {
2704616d0f9Sopenharmony_ci	if (DATAFORM == "rearguard") {
2714616d0f9Sopenharmony_ci	  sub(/\t2018\t/, "\t2017\t")
2724616d0f9Sopenharmony_ci	} else {
2734616d0f9Sopenharmony_ci	  sub(/\t2017\t/, "\t2018\t")
2744616d0f9Sopenharmony_ci	}
2754616d0f9Sopenharmony_ci      }
2764616d0f9Sopenharmony_ci
2774616d0f9Sopenharmony_ci      if (2019 <= $3) {
2784616d0f9Sopenharmony_ci	if ($8 == "2:00") {
2794616d0f9Sopenharmony_ci	  if (DATAFORM == "rearguard") {
2804616d0f9Sopenharmony_ci	    sub(/\t0\t/, "\t1:00\t")
2814616d0f9Sopenharmony_ci	  } else {
2824616d0f9Sopenharmony_ci	    sub(/\t1:00\t/, "\t0\t")
2834616d0f9Sopenharmony_ci	  }
2844616d0f9Sopenharmony_ci	} else {
2854616d0f9Sopenharmony_ci	  if (DATAFORM == "rearguard") {
2864616d0f9Sopenharmony_ci	    sub(/\t-1:00\t/, "\t0\t")
2874616d0f9Sopenharmony_ci	  } else {
2884616d0f9Sopenharmony_ci	    sub(/\t0\t/, "\t-1:00\t")
2894616d0f9Sopenharmony_ci	  }
2904616d0f9Sopenharmony_ci	}
2914616d0f9Sopenharmony_ci      }
2924616d0f9Sopenharmony_ci    }
2934616d0f9Sopenharmony_ci    if ($1 ~ /^[+0-9-]/ && NF == 3) {
2944616d0f9Sopenharmony_ci      if (DATAFORM == "rearguard") {
2954616d0f9Sopenharmony_ci	sub(/1:00\tMorocco/, "0:00\tMorocco")
2964616d0f9Sopenharmony_ci	sub(/\t\+01\/\+00$/, "\t+00/+01")
2974616d0f9Sopenharmony_ci      } else {
2984616d0f9Sopenharmony_ci	sub(/0:00\tMorocco/, "1:00\tMorocco")
2994616d0f9Sopenharmony_ci	sub(/\t\+00\/+01$/, "\t+01/+00")
3004616d0f9Sopenharmony_ci      }
3014616d0f9Sopenharmony_ci    }
3024616d0f9Sopenharmony_ci  }
3034616d0f9Sopenharmony_ci}
3044616d0f9Sopenharmony_ci
3054616d0f9Sopenharmony_ci/^Zone/ {
3064616d0f9Sopenharmony_ci  packrat_ignored = FILENAME == PACKRATDATA && PACKRATLIST && !packratlist[$2];
3074616d0f9Sopenharmony_ci}
3084616d0f9Sopenharmony_ci{
3094616d0f9Sopenharmony_ci  if (packrat_ignored && $0 !~ /^Rule/) {
3104616d0f9Sopenharmony_ci    sub(/^/, "#")
3114616d0f9Sopenharmony_ci  }
3124616d0f9Sopenharmony_ci}
3134616d0f9Sopenharmony_ci
3144616d0f9Sopenharmony_ci# Return a link line resulting by changing OLDLINE to link to TARGET
3154616d0f9Sopenharmony_ci# from LINKNAME, instead of linking to OLDTARGET from LINKNAME.
3164616d0f9Sopenharmony_ci# Align data columns the same as they were in OLDLINE.
3174616d0f9Sopenharmony_ci# Also, replace any existing white space followed by comment with COMMENT.
3184616d0f9Sopenharmony_cifunction make_linkline(oldline, target, linkname, oldtarget, comment, \
3194616d0f9Sopenharmony_ci		       oldprefix, oldprefixlen, oldtargettabs, \
3204616d0f9Sopenharmony_ci		       replsuffix, targettabs)
3214616d0f9Sopenharmony_ci{
3224616d0f9Sopenharmony_ci  oldprefix = "Link\t" oldtarget "\t"
3234616d0f9Sopenharmony_ci  oldprefixlen = length(oldprefix)
3244616d0f9Sopenharmony_ci  if (substr(oldline, 1, oldprefixlen) == oldprefix) {
3254616d0f9Sopenharmony_ci    # Use tab stops to preserve LINKNAME's column.
3264616d0f9Sopenharmony_ci    replsuffix = substr(oldline, oldprefixlen + 1)
3274616d0f9Sopenharmony_ci    sub(/[\t ]*#.*/, "", replsuffix)
3284616d0f9Sopenharmony_ci    oldtargettabs = int(length(oldtarget) / 8) + 1
3294616d0f9Sopenharmony_ci    targettabs = int(length(target) / 8) + 1
3304616d0f9Sopenharmony_ci    for (; targettabs < oldtargettabs; targettabs++) {
3314616d0f9Sopenharmony_ci      replsuffix = "\t" replsuffix
3324616d0f9Sopenharmony_ci    }
3334616d0f9Sopenharmony_ci    for (; oldtargettabs < targettabs && replsuffix ~ /^\t/; targettabs--) {
3344616d0f9Sopenharmony_ci      replsuffix = substr(replsuffix, 2)
3354616d0f9Sopenharmony_ci    }
3364616d0f9Sopenharmony_ci  } else {
3374616d0f9Sopenharmony_ci    # Odd format line; don't bother lining up its replacement nicely.
3384616d0f9Sopenharmony_ci    replsuffix = linkname
3394616d0f9Sopenharmony_ci  }
3404616d0f9Sopenharmony_ci  return "Link\t" target "\t" replsuffix comment
3414616d0f9Sopenharmony_ci}
3424616d0f9Sopenharmony_ci
3434616d0f9Sopenharmony_ci/^Link/ && $4 == "#=" && DATAFORM == "vanguard" {
3444616d0f9Sopenharmony_ci  $0 = make_linkline($0, $5, $3, $2)
3454616d0f9Sopenharmony_ci}
3464616d0f9Sopenharmony_ci
3474616d0f9Sopenharmony_ci# If a Link line is followed by a Link or Zone line for the same data, comment
3484616d0f9Sopenharmony_ci# out the Link line.  This can happen if backzone overrides a Link
3494616d0f9Sopenharmony_ci# with a Zone or a different Link.
3504616d0f9Sopenharmony_ci/^Zone/ {
3514616d0f9Sopenharmony_ci  sub(/^Link/, "#Link", line[linkline[$2]])
3524616d0f9Sopenharmony_ci}
3534616d0f9Sopenharmony_ci/^Link/ {
3544616d0f9Sopenharmony_ci  sub(/^Link/, "#Link", line[linkline[$3]])
3554616d0f9Sopenharmony_ci  linkline[$3] = NR
3564616d0f9Sopenharmony_ci  linktarget[$3] = $2
3574616d0f9Sopenharmony_ci}
3584616d0f9Sopenharmony_ci
3594616d0f9Sopenharmony_ci{ line[NR] = $0 }
3604616d0f9Sopenharmony_ci
3614616d0f9Sopenharmony_cifunction cut_link_chains_short( \
3624616d0f9Sopenharmony_ci			       l, linkname, t, target)
3634616d0f9Sopenharmony_ci{
3644616d0f9Sopenharmony_ci  for (linkname in linktarget) {
3654616d0f9Sopenharmony_ci    target = linktarget[linkname]
3664616d0f9Sopenharmony_ci    t = linktarget[target]
3674616d0f9Sopenharmony_ci    if (t) {
3684616d0f9Sopenharmony_ci      # TARGET is itself a link name.  Replace the line "Link TARGET LINKNAME"
3694616d0f9Sopenharmony_ci      # with "Link T LINKNAME #= TARGET", where T is at the end of the chain
3704616d0f9Sopenharmony_ci      # of links that LINKNAME points to.
3714616d0f9Sopenharmony_ci      while ((u = linktarget[t])) {
3724616d0f9Sopenharmony_ci	t = u
3734616d0f9Sopenharmony_ci      }
3744616d0f9Sopenharmony_ci      l = linkline[linkname]
3754616d0f9Sopenharmony_ci      line[l] = make_linkline(line[l], t, linkname, target, "\t#= " target)
3764616d0f9Sopenharmony_ci    }
3774616d0f9Sopenharmony_ci  }
3784616d0f9Sopenharmony_ci}
3794616d0f9Sopenharmony_ci
3804616d0f9Sopenharmony_ciEND {
3814616d0f9Sopenharmony_ci  if (DATAFORM != "vanguard") {
3824616d0f9Sopenharmony_ci    cut_link_chains_short()
3834616d0f9Sopenharmony_ci  }
3844616d0f9Sopenharmony_ci  for (i = 1; i <= NR; i++)
3854616d0f9Sopenharmony_ci    print line[i]
3864616d0f9Sopenharmony_ci}
387