text:
#import "LWImageStorage.h"
#import "GallopDefine.h"
#import "LWAsyncDisplayLayer.h"
#import "UIImage+Gallop.h"
#import "GallopUtils.h"

@interface LWImageStorage()

@property (nonatomic,assign) BOOL needRerendering;

@end

@implementation LWImageStorage

@synthesize cornerRadius = _cornerRadius;
@synthesize cornerBorderWidth = _cornerBorderWidth;

#pragma mark - NSCopying

- (id)copyWithZone:(NSZone *)zone {
    LWImageStorage* one = [[LWImageStorage alloc] init];
    if ([self.contents conformsToProtocol:@protocol(NSCopying)]) {
        one.contents = [self.contents copy];
    } else {
        one.contents = self.contents;
    }
    one.localImageType = self.localImageType;
    one.placeholder = [self.placeholder copy];
    one.fadeShow = self.fadeShow;
    one.userInteractionEnabled = self.userInteractionEnabled;
    one.needRerendering = self.needRerendering;
    one.needResize = self.needResize;
    one.isBlur = self.isBlur;
    one.identifier = [self.identifier copy];
    one.tag = self.tag;
    one.clipsToBounds = self.clipsToBounds;
    one.opaque = self.opaque;
    one.hidden = self.hidden;
    one.alpha = self.alpha;
    one.frame = self.frame;
    one.bounds = self.bounds;
    one.center = self.center;
    one.position = self.position;
    one.cornerRadius = self.cornerRadius;
    one.cornerBackgroundColor = [self.cornerBackgroundColor copy];
    one.cornerBorderColor = [self.cornerBorderColor copy];
    one.cornerBorderWidth = self.cornerBorderWidth;
    one.shadowColor = self.shadowColor;
    one.shadowOpacity = self.shadowOpacity;
    one.shadowOffset = self.shadowOffset;
    one.shadowRadius = self.shadowRadius;
    one.contentsScale = self.contentsScale;
    one.backgroundColor = [self.backgroundColor copy];
    one.contentMode = self.contentMode;
    one.htmlLayoutEdgeInsets = self.htmlLayoutEdgeInsets;
    one.extraDisplayIdentifier = [self.extraDisplayIdentifier copy];
    return one;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return [self copyWithZone:zone];
}

#pragma mark - NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.contents forKey:@"contents"];
    [aCoder encodeInteger:self.localImageType forKey:@"localImageType"];
    [aCoder encodeObject:self.placeholder forKey:@"placeholder"];
    [aCoder encodeBool:self.fadeShow forKey:@"fadeShow"];
    [aCoder encodeBool:self.userInteractionEnabled forKey:@"userInteractionEnabled"];
    [aCoder encodeBool:self.needRerendering forKey:@"needRerendering"];
    [aCoder encodeBool:self.needResize forKey:@"needResize"];
    [aCoder encodeBool:self.isBlur forKey:@"isBlur"];
    [aCoder encodeObject:self.identifier forKey:@"identifier"];
    [aCoder encodeInteger:self.tag forKey:@"tag"];
    [aCoder encodeBool:self.clipsToBounds forKey:@"clipsToBounds"];
    [aCoder encodeBool:self.opaque forKey:@"opaque"];
    [aCoder encodeBool:self.hidden forKey:@"hidden"];
    [aCoder encodeFloat:self.alpha forKey:@"alpha"];
    [aCoder encodeCGRect:self.frame forKey:@"frame"];
    [aCoder encodeCGRect:self.bounds forKey:@"bounds"];
    [aCoder encodeFloat:self.height forKey:@"height"];
    [aCoder encodeFloat:self.width forKey:@"width"];
    [aCoder encodeFloat:self.left forKey:@"left"];
    [aCoder encodeFloat:self.right forKey:@"right"];
    [aCoder encodeFloat:self.top forKey:@"top"];
    [aCoder encodeFloat:self.bottom forKey:@"bottom"];
    [aCoder encodeCGPoint:self.center forKey:@"center"];
    [aCoder encodeCGPoint:self.position forKey:@"position"];
    [aCoder encodeFloat:self.cornerRadius forKey:@"cornerRadius"];
    [aCoder encodeObject:self.cornerBackgroundColor forKey:@"cornerBackgroundColor"];
    [aCoder encodeObject:self.cornerBorderColor forKey:@"cornerBorderColor"];
    [aCoder encodeFloat:self.cornerBorderWidth forKey:@"cornerBorderWidth"];
    [aCoder encodeObject:self.shadowColor forKey:@"shadowColor"];
    [aCoder encodeFloat:self.shadowOpacity forKey:@"shadowOpacity"];
    [aCoder encodeCGSize:self.shadowOffset forKey:@"shadowOffset"];
    [aCoder encodeFloat:self.shadowRadius forKey:@"shadowRadius"];
    [aCoder encodeFloat:self.contentsScale forKey:@"contentsScale"];
    [aCoder encodeObject:self.backgroundColor forKey:@"backgroundColor"];
    [aCoder encodeInteger:self.contentMode forKey:@"contentMode"];
    [aCoder encodeUIEdgeInsets:self.htmlLayoutEdgeInsets forKey:@"htmlLayoutEdgeInsets"];
    [aCoder encodeObject:self.extraDisplayIdentifier forKey:@"extraDisplayIdentifier"];
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        self.contents = [aDecoder decodeObjectForKey:@"contents"];
        self.placeholder = [aDecoder decodeObjectForKey:@"placeholder"];
        self.localImageType = [aDecoder decodeIntegerForKey:@"localImageType"];
        self.fadeShow = [aDecoder decodeBoolForKey:@"fadeShow"];
        self.userInteractionEnabled = [aDecoder decodeBoolForKey:@"userInteractionEnabled"];
        self.needResize = [aDecoder decodeBoolForKey:@"needResize"];
        self.needRerendering = [aDecoder decodeBoolForKey:@"needRerendering"];
        self.isBlur = [aDecoder decodeBoolForKey:@"isBlur"];
        self.identifier = [aDecoder decodeObjectForKey:@"identifier"];
        self.tag = [aDecoder decodeIntegerForKey:@"tag"];
        self.clipsToBounds = [aDecoder decodeBoolForKey:@"clipsToBounds"];
        self.opaque = [aDecoder decodeBoolForKey:@"opaque"];
        self.hidden = [aDecoder decodeBoolForKey:@"hidden"];
        self.alpha = [aDecoder decodeFloatForKey:@"alpha"];
        self.frame = [aDecoder decodeCGRectForKey:@"frame"];
        self.bounds = [aDecoder decodeCGRectForKey:@"bounds"];
        self.center = [aDecoder decodeCGPointForKey:@"center"];
        self.position = [aDecoder decodeCGPointForKey:@"position"];
        self.cornerRadius = [aDecoder decodeFloatForKey:@"cornerRadius"];
        self.cornerBackgroundColor = [aDecoder decodeObjectForKey:@"cornerBackgroundColor"];
        self.cornerBorderColor = [aDecoder decodeObjectForKey:@"cornerBorderColor"];
        self.cornerBorderWidth = [aDecoder decodeFloatForKey:@"cornerBorderWidth"];
        self.shadowColor = [aDecoder decodeObjectForKey:@"shadowColor"];
        self.shadowOpacity = [aDecoder decodeFloatForKey:@"shadowOpacity"];
        self.shadowOffset = [aDecoder decodeCGSizeForKey:@"shadowOffset"];
        self.shadowRadius = [aDecoder decodeFloatForKey:@"shadowRadius"];
        self.contentsScale = [aDecoder decodeFloatForKey:@"contentsScale"];
        self.backgroundColor = [aDecoder decodeObjectForKey:@"backgroundColor"];
        self.contentMode = [aDecoder decodeIntegerForKey:@"contentMode"];
        self.htmlLayoutEdgeInsets = [aDecoder decodeUIEdgeInsetsForKey:@"htmlLayoutEdgeInsets"];
        self.extraDisplayIdentifier = [aDecoder decodeObjectForKey:@"extraDisplayIdentifier"];
    }
    return self;
}

#pragma mark - LifeCycle

- (id)init {
    self = [super init];
    if (self) {
        self.contents = nil;
        self.userInteractionEnabled = YES;
        self.placeholder = nil;
        self.fadeShow = YES;
        self.clipsToBounds = NO;
        self.contentsScale = [GallopUtils contentsScale];
        self.needRerendering = NO;
        self.needResize = NO;
        self.localImageType = LWLocalImageDrawInLWAsyncDisplayView;
        self.isBlur = NO;
    }
    return self;
}

- (BOOL)needRerendering {
    if (self.cornerBorderWidth != 0 || self.cornerRadius != 0) {
        return YES;
    }
    else {
        return _needRerendering;
    }
}

#pragma mark - Methods

- (void)stretchableImageWithLeftCapWidth:(CGFloat)leftCapWidth topCapHeight:(NSInteger)topCapHeight {
    if ([self.contents isKindOfClass:[UIImage class]] &&
        self.localImageType == LWLocalImageDrawInLWAsyncDisplayView) {
        self.contents = [(UIImage *)self.contents
                         stretchableImageWithLeftCapWidth:leftCapWidth
                         topCapHeight:topCapHeight];
    }
}

- (void)lw_drawInContext:(CGContextRef)context isCancelled:(LWAsyncDisplayIsCanclledBlock)isCancelld {

    if (isCancelld()) {
        return;
    }

    if ([self.contents isKindOfClass:[NSURL class]]) {
        return;
    }

    if ([self.contents isKindOfClass:[UIImage class]] &&
        self.localImageType == LWLocalImageDrawInLWAsyncDisplayView) {
        UIImage* image = (UIImage *)self.contents;
        BOOL isOpaque = self.opaque;
        UIColor* backgroundColor = self.backgroundColor;
        CGFloat cornerRaiuds = self.cornerRadius;
        UIColor* cornerBackgroundColor = self.cornerBackgroundColor;
        UIColor* cornerBorderColor = self.cornerBorderColor;
        CGFloat cornerBorderWidth = self.cornerBorderWidth;
        CGRect rect = self.frame;
        rect = CGRectStandardize(rect);

        CGRect imgRect = {
            {rect.origin.x + cornerBorderWidth,rect.origin.y + cornerBorderWidth},
            {rect.size.width - 2 * cornerBorderWidth,rect.size.height - 2 * cornerBorderWidth}
        };

        if (!image) {
            return;
        }

        if (self.isBlur) {
            image = [image lw_applyBlurWithRadius:20
                                        tintColor:RGB(0, 0, 0, 0.15f)
                            saturationDeltaFactor:1.4
                                        maskImage:nil];
        }

        CGContextSaveGState(context);
        if (isOpaque && backgroundColor) {
            [backgroundColor setFill];
            UIRectFill(imgRect);
        }

        UIBezierPath* backgroundRect = [UIBezierPath bezierPathWithRect:imgRect];
        UIBezierPath* cornerPath = [UIBezierPath bezierPathWithRoundedRect:imgRect
                                                              cornerRadius:cornerRaiuds];

        if (cornerBackgroundColor) {
            [cornerBackgroundColor setFill];
            [backgroundRect fill];
        }
        [cornerPath addClip];

        [image lw_drawInRect:imgRect
                 contentMode:self.contentMode
               clipsToBounds:YES];

        CGContextRestoreGState(context);
        if (cornerBorderColor && cornerBorderWidth != 0) {
            [cornerPath setLineWidth:cornerBorderWidth];
            [cornerBorderColor setStroke];
            [cornerPath stroke];
        }
    }
}

@end

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <title>BMS Generator</title>
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>

    <link rel="stylesheet" href="{{ URL::asset('css/bootstrap.min.css') }}">
    <link rel="stylesheet" href="{{ URL::asset('css/font-awesome.min.css') }}">
    <link rel="stylesheet" href="{{ URL::asset('css/AdminLTE.min.css') }}">
    <link rel="stylesheet" href="{{ URL::asset('css/_all-skins.min.css') }}">

    <link rel="stylesheet" href="{{ URL::asset('css/ionicons.min.css') }}">

    @yield('css')
    @include('UEditor::head')

                BMS

                    Toggle navigation

            @yield('content')

            Copyright © 2016 Company. All rights reserved.

    @yield('scripts')


text:
/*! Declan Carter
    February 2019
*/
#include "Semaphore.h"
#include <iostream>
#include <thread>
#include <vector>
/*! \Mutual Exclusion Lab
  \mainpage Using a semaphore to lock the loop to stop other threads from being able to accessing it while another thread is currently using it. Once the thread has finished it signals to the next thread to continue.
   Uses C++11 features such as mutex and condition variables to implement Semaphores in thread functions
*/
static const int num_threads = 100;
int sharedVariable=0;

/*! \fn updateTask
    \brief An Implementation of Mutual Exclusion using Semaphores

*/
/*!
    \brief displays a message that is split in to 2 sections to show how a rendezvous works
    firstSem sends a wait to lock the loop, not allowing any other thread to use the loop until
    they are signaled.
*/
void updateTask(std::shared_ptr<Semaphore> firstSem, int numUpdates){

  firstSem->Wait();
  for(int i=0;i<numUpdates;i++){
      sharedVariable++;
  }
  firstSem->Signal();

}

int main(void){
  std::vector<std::thread> vt(num_threads);
  std::shared_ptr<Semaphore> aSemaphore( new Semaphore(1));
  /**< Launch the threads  */
  for(std::thread& t: vt){
    t=std::thread(updateTask,aSemaphore,1000);
  }
  std::cout << "Launched from the main\n";
  /**< Join the threads with the main thread */
  for (auto& v :vt){
      v.join();
  }
  std::cout << sharedVariable << std::endl;
  return 0;
}


text:
import Wreqr from 'backbone.wreqr';
import Marionette from 'backbone.marionette';
import DeviceHelper from 'helper/device';
import template from 'templates/user/userThemesColumn.ejs';
import NavPillsStackedListView from 'ui/navPillsStacked';
import SearchInput from 'ui/form/searchInput';
import Locale from 'core/locale';
import ThemeCore from 'core/theme';

export default Marionette.LayoutView.extend({
  template,

  behaviors() {
    return {
      l20n: {},
      column: {
        appendToBody: true,
        destroyOnClose: true,
        routeOnClose: this.options.previousRoute
      }
    };
  },

  regions: {
    searchInput: '.rg_search_input',
    themesNav: '.rg_themes_nav'
  },

  ui: {
    column: '.column',
    themesNav: '.rg_themes_nav',
    stickyInner: '.sticky-inner',
    noResult: '.no_result',
    backButton: '.back_btn'
  },

  events: {
    'click @ui.backButton': '_onClickBack'
  },

  initialize() {
    this._radio = Wreqr.radio.channel('global');
    this._app = this.options.app;
    this._window = this._app.getWindow();
    this._config = this._app.getConfig();
    this._deviceHelper = new DeviceHelper(this._config, this._window);
  },

  onBeforeOpen() {
    this._radio.vent.trigger('column:closeAll', [this.cid]);
    this._radio.vent.trigger('widget:closeAll', [this.cid]);
  },

  open() {
    this.triggerMethod('open');
    return this;
  },

  close() {
    this.triggerMethod('close');
    return this;
  },

  onRender() {
    this._themesNav = new NavPillsStackedListView();
    this._defaultNavItems = this._buildNavItems(this.collection);

    this._setDefaultNavItems();
    this.getRegion('themesNav').show(this._themesNav);

    this._searchInput = new SearchInput({
      charactersMin: 1,
      placeholder: document.l10n.getSync('search')
    });

    this.getRegion('searchInput').show(this._searchInput);

    if (this._deviceHelper.isTallScreen() === true) {
      this._searchInput.setFocus();
    }

    this._searchInput.on(
      'search',
      this._filterNavItems.bind(this, this._defaultNavItems),
      this
    );
    this._searchInput.on('empty', this._setDefaultNavItems, this);
  },

  _buildNavItems(collection) {
    return collection.models.map(theme => ({
      label: Locale.getLocalized(theme, 'name'),
      href: ThemeCore.buildPath(theme.get('fragment'), theme.get('name'))
    }));
  },

  _setDefaultNavItems() {
    this._hideNoResult();

    this._themesNav.setItems(this._defaultNavItems);
  },

  _filterNavItems(defaultNavItems, searchString) {
    this._searchInput.trigger('search:success');
    this._hideNoResult();

    const re = new RegExp(searchString, 'i');
    const navItems = defaultNavItems.filter(item => re.test(item.label));

    this._themesNav.setItems(navItems);

    if (navItems.length === 0) {
      this._showNoResult();
    }
  },

  _hideNoResult() {
    this.ui.noResult.addClass('hide');
  },

  _showNoResult() {
    this.ui.noResult.removeClass('hide');
  },

  _onClickBack() {
    this.options.router.navigate('user', true);
  }
});


text:
from urllib.request import urlopen

def Check(user):
    # get the url
    url = 'https://minecraft.net/haspaid.jsp?user=%s' % (user)

    # opens url and reads it (and stores it in string)
    resp = urlopen(url)
    html = resp.read()
    html = str(html)

    #  this is the part that checks is user is premium or not

    # if the success label in the html code (if user is premium) then print
    if('true' in html): return True
    # else if success label NOT in html then print
    elif('false' in html): return False
    # if a strange error has occured
    else: raise('error')

def usage():
    print('SEE TESTS.PY FOR EXAMPLES')

if __name__ == "__main__":
    usage()


text:
#include "tensorflow/core/profiler/lib/profiler_session.h"

#include <memory>
#include <utility>

#include "absl/memory/memory.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/mutex.h"
#include "tensorflow/core/platform/platform.h"
#include "tensorflow/core/platform/status.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/profiler/protobuf/xplane.pb.h"
#include "tensorflow/tsl/profiler/protobuf/profiler_options.pb.h"

#if !defined(IS_MOBILE_PLATFORM)
#include "tensorflow/core/platform/host_info.h"
#include "tensorflow/core/profiler/convert/post_process_single_host_xplane.h"
#include "tensorflow/core/profiler/lib/profiler_collection.h"
#include "tensorflow/core/profiler/lib/profiler_factory.h"
#include "tensorflow/core/profiler/lib/profiler_interface.h"
#include "tensorflow/core/profiler/lib/profiler_lock.h"
#include "tensorflow/core/profiler/utils/time_utils.h"
#endif

namespace tensorflow {
namespace {

ProfileOptions GetOptions(const ProfileOptions& opts) {
  if (opts.version()) return opts;
  ProfileOptions options = ProfilerSession::DefaultOptions();
  options.set_include_dataset_ops(opts.include_dataset_ops());
  return options;
}

};  // namespace

/*static*/ std::unique_ptr<ProfilerSession> ProfilerSession::Create(
    const ProfileOptions& options) {
  return absl::WrapUnique(new ProfilerSession(options));
}

tensorflow::Status ProfilerSession::Status() {
  mutex_lock l(mutex_);
  return status_;
}

#if !defined(IS_MOBILE_PLATFORM)
Status ProfilerSession::CollectDataInternal(profiler::XSpace* space) {
  mutex_lock l(mutex_);
  TF_RETURN_IF_ERROR(status_);
  LOG(INFO) << "Profiler session collecting data.";
  if (profilers_ != nullptr) {
    profilers_->Stop().IgnoreError();
    profilers_->CollectData(space).IgnoreError();
    profilers_.reset();  // data has been collected.
  }
  // Allow another session to start.
  profiler_lock_.ReleaseIfActive();
  return OkStatus();
}
#endif

Status ProfilerSession::CollectData(profiler::XSpace* space) {
#if !defined(IS_MOBILE_PLATFORM)
  space->add_hostnames(port::Hostname());
  TF_RETURN_IF_ERROR(CollectDataInternal(space));
  PostProcessSingleHostXSpace(space, start_time_ns_);
#endif
  return OkStatus();
}

ProfilerSession::ProfilerSession(const ProfileOptions& options)
#if defined(IS_MOBILE_PLATFORM)
    : status_(errors::Unimplemented(
          "Profiler is unimplemented for mobile platforms.")) {
#else
    : options_(GetOptions(options)) {
  auto profiler_lock = profiler::ProfilerLock::Acquire();
  if (!profiler_lock.ok()) {
    status_ = profiler_lock.status();
    return;
  }
  profiler_lock_ = *std::move(profiler_lock);

  LOG(INFO) << "Profiler session initializing.";
  // Sleep until it is time to start profiling.
  if (options_.start_timestamp_ns() > 0) {
    int64_t sleep_duration_ns =
        options_.start_timestamp_ns() - profiler::GetCurrentTimeNanos();
    if (sleep_duration_ns < 0) {
      LOG(WARNING) << "Profiling is late by " << -sleep_duration_ns
                   << " nanoseconds and will start immediately.";
    } else {
      LOG(INFO) << "Delaying start of profiler session by "
                << sleep_duration_ns;
      profiler::SleepForNanos(sleep_duration_ns);
    }
  }

  LOG(INFO) << "Profiler session started.";
  start_time_ns_ = profiler::GetCurrentTimeNanos();

  DCHECK(profiler_lock_.Active());
  profilers_ = absl::make_unique<profiler::ProfilerCollection>(
      profiler::CreateProfilers(options_));
  profilers_->Start().IgnoreError();
#endif
}

ProfilerSession::~ProfilerSession() {
#if !defined(IS_MOBILE_PLATFORM)
  LOG(INFO) << "Profiler session tear down.";
#endif
}

}  // namespace tensorflow


text:
<!DOCTYPE html>

	<title>10-4 Good Main Street</title>

<meta charset="UTF-8">
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="content" content="">

<meta name="generator">
<meta name="robots" content="index, follow">

<link rel="stylesheet" href="css/10-4.css">

<link href='http://fonts.googleapis.com/css?family=Rokkitt:400,700' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Oleo+Script:700' rel='stylesheet' type='text/css'>

	Home  |  Ideas  |  Prototypes  |  Products

WE'RE GONNA DO WHAT THEY SAY CAN'T BE DONE

10-4 Good City a place to focus on some of the more popular ideas of What If Greenville. We'd like to discuss
			the idea and find out if people are interested in turning this idea to action.

Our first topic is a walkable Main Street. At least a half dozen people submitted this idea and below is a
			Greenville News editorial by Marc Bolick of DMarc8 on why he thinks this is a good idea.

Walking On Main Street

By Marc Bolick

We've all heard the story. Greenville's downtown used to be an anti-destination. It is where you didn't go at night or on the weekends. That has changed now, and we are all proud to show visitors how wonderful our Main Street area is. But if you had asked the average person 20 years ago whether Main Street could be a thriving hub of restaurants, shops and street festivals, most would have said "no way!"

By all accounts, the vision of Greenville's leaders over three decades ago has proven accurate: if you build an attractive streetscape and provide the right incentives, you can create a vibrant and thriving downtown. I think that a key aspect of the revitalization of downtown was the so-called "road diet" that was imposed on Main Street, reducing it from four lanes to two. This was done intentionally to make the area more pedestrian friendly. So, my question now is, why not go all the way and make a large portion of Main Street pedestrian-only?

Think about it. When you head downtown and you turn onto Main Street anywhere between College and Broad, you just know that you're going to end up driving slow and have very little chance of finding parking on Main itself. Just the other day around lunchtime I stood in front of the Westin Poinsett and looked north up Main Street. All I could see were cars waiting at traffic lights. I stood there imagining what it would be like to have no cars, no parking, just a wide pedestrian area with more outdoor restaurant seating, a bike lane and maybe an electric bus or trolley running down the center of Main.

Many people will object to this idea, and the arguments against are important to consider. Retailers on Main Street would lose the vital drive-by traffic that attracts walk-in customers. Parking capacity would be reduced (around 100 spaces). And, perhaps most compellingly, the argument is made that pedestrianisation has been tried in other US cities and "it didn't work." These are all good points, and any new street design should take these and other considerations into account.

But, let's remember the arguments against tearing down the "perfectly good" Camperdown bridge that is now the Liberty (walking!) Bridge. That $13 million public investment in the Falls Park project stimulated well over $100 million in private investment that has transformed downtown Greenville. Our Main Street has become a case study for cities across the country and internationally for how to revitalize a city. We should continue to lead and make Greenville's Main Street a pedestrianised area, for the health of the city's economy and for the health of our citizens.

				1

Submit Your Idea

<input id="" name="saveForm" class="btn" type="submit" value="What If Greenville"/>

				2

Spread the Word

Love the idea? Hate the idea? Please share  with your friends, family, and enemies.

				3

Sign Up For Updates

Get weekly updates of new ideas submitted to What If and updates on this project specifically.

<link href="http://cdn-images.mailchimp.com/embedcode/slim-081711.css" rel="stylesheet" type="text/css">

<form action="http://orangecoat.us1.list-manage.com/subscribe/post?u=b9c28aacc32cfe32eb1a24fc2&id=f5c51447e2" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
	<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required>

<input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="btn">

</form>

brought to you by OrangeCoat with moral support from Greenville Forward.


text:
#ifndef CQChartsModelDetailsWidget_H
#define CQChartsModelDetailsWidget_H

#include <CQChartsWidgetIFace.h>

#include <QFrame>
#include <QPointer>

class CQChartsModelData;
class CQChartsModelDetailsTable;
class CQCharts;
class CQLabel;

class QPushButton;
class QLabel;
class QCheckBox;

/*!
 * \brief Model Details Widget
 * \ingroup Charts
 */
class CQChartsModelDetailsWidget : public QFrame, public CQChartsWidgetIFace {
  Q_OBJECT

  Q_PROPERTY(bool flip READ isFlip WRITE setFlip)

 public:
  using ModelData    = CQChartsModelData;
  using DetailsTable = CQChartsModelDetailsTable;

 public:
  CQChartsModelDetailsWidget(CQCharts *charts=nullptr);

  //! get/set flip
  bool isFlip() const;
  void setFlip(bool b);

  void setCharts(CQCharts *charts) override;

  void setModelData(ModelData *modelData) override;

  void invalidateModelData(ModelData *modelData, bool invalidate=true);

  void invalidate();

 private Q_SLOTS:
  void invalidateSlot();
  void flipSlot(int state);
  void updateSlot();

 private:
  using ModelDataP = QPointer<ModelData>;

  CQCharts*     charts_          { nullptr };
  ModelDataP    modelData_;
  QLabel*       modelLabel_      { nullptr };
  QPushButton*  updateButton_    { nullptr };
  CQLabel*      numColumnsLabel_ { nullptr };
  CQLabel*      numRowsLabel_    { nullptr };
  QLabel*       hierLabel_       { nullptr };
  QCheckBox*    flipCheck_       { nullptr };
  DetailsTable* detailsTable_    { nullptr };
};

#endif


text:
#ifndef _WX_ANYSTR_H_
#define _WX_ANYSTR_H_

#include "wx/string.h"

// ----------------------------------------------------------------------------
// wxAnyStrPtr
//
// Notice that this is an internal and intentionally not documented class. It
// is only used by wxWidgets itself to ensure compatibility with previous
// versions and shouldn't be used by user code. When you see a function
// returning it you should just know that you can treat it as a string pointer.
// ----------------------------------------------------------------------------

// This is a helper class convertible to either narrow or wide string pointer.
// It is similar to wxCStrData but, unlike it, can be NULL which is required to
// represent the return value of wxDateTime::ParseXXX() methods for example.
//
// NB: this class is fully inline and so doesn't need to be DLL-exported
class wxAnyStrPtr
{
public:
    // ctors: this class must be created from the associated string or using
    // its default ctor for an invalid NULL-like object; notice that it is
    // immutable after creation.

    // ctor for invalid pointer
    wxAnyStrPtr()
        : m_str(NULL)
    {
    }

    // ctor for valid pointer into the given string (whose lifetime must be
    // greater than ours and which should remain constant while we're used)
    wxAnyStrPtr(const wxString& str, const wxString::const_iterator& iter)
        : m_str(&str),
          m_iter(iter)
    {
    }

    // default copy ctor is ok and so is default dtor, in particular we do not
    // free the string

    // various operators meant to make this class look like a superposition of
    // char* and wchar_t*

    // this one is needed to allow boolean expressions involving these objects,
    // e.g. "if ( FuncReturningAnyStrPtr() && ... )" (unfortunately using
    // unspecified_bool_type here wouldn't help with ambiguity between all the
    // different conversions to pointers)
    operator bool() const { return m_str != NULL; }

    // at least VC6 and VC7 also need this one or they complain about ambiguity
    // for !anystr expressions
    bool operator!() const { return !((bool)*this); }

    // and these are the conversions operator which allow to assign the result
    // of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*)
    operator const char *() const
    {
        if ( !m_str )
            return NULL;

        // check if the string is convertible to char at all
        //
        // notice that this pointer points into wxString internal buffer
        // containing its char* representation and so it can be kept for as
        // long as wxString is not modified -- which is long enough for our
        // needs
        const char *p = m_str->c_str().AsChar();
        if ( *p )
        {
            // find the offset of the character corresponding to this iterator
            // position in bytes: we don't have any direct way to do it so we
            // need to redo the conversion again for the part of the string
            // before the iterator to find its length in bytes in current
            // locale
            //
            // NB: conversion won't fail as it succeeded for the entire string
            p += strlen(wxString(m_str->begin(), m_iter).mb_str());
        }
        //else: conversion failed, return "" as we can't do anything else

        return p;
    }

    operator const wchar_t *() const
    {
        if ( !m_str )
            return NULL;

        // no complications with wide strings (as long as we discount
        // surrogates as we do for now)
        //
        // just remember that this works as long as wxString keeps an internal
        // buffer with its wide wide char representation, just as with AsChar()
        // above
        return m_str->c_str().AsWChar() + (m_iter - m_str->begin());
    }

    // Because the objects of this class are only used as return type for
    // functions which can return NULL we can skip providing dereferencing
    // operators: the code using this class must test it for NULL first and if
    // it does anything else with it it has to assign it to either char* or
    // wchar_t* itself, before dereferencing.
    //
    // IOW this
    //
    //      if ( *FuncReturningAnyStrPtr() )
    //
    // is invalid because it could crash. And this
    //
    //      const char *p = FuncReturningAnyStrPtr();
    //      if ( p && *p )
    //
    // already works fine.

private:
    // the original string and the position in it we correspond to, if the
    // string is NULL this object is NULL pointer-like
    const wxString * const m_str;
    const wxString::const_iterator m_iter;

    wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr);
};

#endif // _WX_ANYSTR_H_


text:
Tutorial
--------

Python uses C-style string formatting to create new, formatted strings. The "%" operator is used to format a set of variables enclosed in a "tuple" (a fixed size list), together with a format string, which contains normal text together with "argument specifiers", special symbols like "%s" and "%d".

Let's say you have a variable called "name" with your user name in it, and you would then like to print out a greeting to that user.

    # This prints out "Hello, John!"
    name = "John"
    print "Hello, %s!" % name

To use two or more argument specifiers, use a tuple (parentheses):

    # This prints out "John is 23 years old."
    name = "John"
    age = 23
    print "%s is %d years old." % (name, age)

Any object which is not a string can be formatted using the %s operator as well. The string which returns from the "repr" method of that object is formatted as the string. For example:

    # This prints out: A list: [1, 2, 3]
    mylist = [1,2,3]
    print "A list: %s" % mylist

Here are some basic argument specifiers you should know:

    %s - String (or any object with a string representation, like numbers)
    %d - Integers
    %f - Floating point numbers
    %.<number of digits>f - Floating point numbers with a fixed amount of digits to the right of the dot.
    %x/%X - Integers in hex representation (lowercase/uppercase)

Exercise
--------

You will need to write a format string which prints out the data using the following syntax:
    Hello John Doe. Your current balance is 53.44$.

Tutorial Code
-------------

data = ("John", "Doe", 53.44)
format_string = "Hello"

print format_string % data

Expected Output
---------------

Hello John Doe. Your current balance is 53.44$.

Solution
--------

data = ("John", "Doe", 53.44)
format_string = "Hello %s %s. Your current balance is %s$."

print format_string % data


text:
import genpy
import rospy
from std_msgs.msg import String
import roslib
import roslib.message

def sender(msg,reciver, msg_type):
	#reciver -> String
	#msg -> obj
	#rospy.loginfo("sender " + reciver)

	msg_class = roslib.message.get_message_class(msg_type)
	pub = rospy.Publisher(reciver, msg_class , queue_size=0)
	#rospy.loginfo(msg)
	rate = rospy.Rate(10)

	x=1
	while x<2 :
		pub.publish(msg)
		rate.sleep()
		x=x+1
	#rospy.loginfo("sended ")
	#rospy.spin()

def sender1(msg, reciver, msg_type):
	#reciver -> String
	#msg -> obj
	#rospy.init_node('sender', anonymous=True)
	#rospy.loginfo("sender " + reciver)
	msg_class = roslib.message.get_message_class(msg_type)
	pub = rospy.Publisher(reciver, msg_class , queue_size=0)
	#rospy.loginfo(msg)
	# type-case using YAML
	try:
		pub_args = []
		for m in msg:
			pub_args.append(yaml.load(m))

	except Exception as e:
		parser.error("Argument error: "+str(e))
	rate = rospy.Rate(10)
	msg = msg_class()
	now = rospy.get_rostime()
	import std_msgs.msg
	keys = { 'now': now, 'auto': std_msgs.msg.Header(stamp=now) }
	genpy.message.fill_message_args(msg, pub_args, keys=keys)
	x=0
	while x<2 :
		pub.publish(msg)
		rate.sleep()
		x=x+1
	#rospy.loginfo("sended ")
	rospy.spin()


text:
<!--
   This file is part of the X12Parser library that provides tools to
   manipulate X12 messages using Ruby native syntax.

   http://x12parser.rubyforge.org

   Copyright (C) 2009 APP Design, Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

   $Id: PCL.xml 78 2009-05-12 22:27:26Z ikk $
-->

<Segment name="PCL" comment="To provide the receiving educational institution or agency with information concerning the student's previous postsecondary education experience">
  <Field name="IdentificationCodeQualifier" required="y" min="1" max="2" validation="T66" comment="Code designating the system/method of code structure used for Identification Code (67)"/>
  <Field name="IdentificationCode" required="y" min="2" max="80" comment="Code identifying a party or other code"/>
  <Field name="DateTimePeriodFormatQualifier" required="y" min="2" max="3" validation="T1250" comment="Code indicating the date format, time format, or date and time format"/>
  <Field name="DateTimePeriod1" required="y" min="1" max="35" comment="Expression of a date, a time, or range of dates, times or dates and times"/>
  <Field name="AcademicDegreeCode" required="y" min="3" max="3" comment="Code indicating the level of postsecondary academic award earned"/>
  <Field name="DateTimePeriod2" required="y" min="1" max="35" comment="Expression of a date, a time, or range of dates, times or dates and times"/>
  <Field name="Description" required="y" min="1" max="80" comment="A free-form description to clarify the related data elements and their content"/>
</Segment>


text:
using System;

namespace EPiServer.Integration.Client.Models.Order
{
    ///
    /// Order address.
    ///
    [Serializable]
    public class OrderAddress
    {
        /// Gets the order group address id.
        /// <value>The order group address id.</value>
        public int OrderGroupAddressId { get; set; }

        /// Gets or sets the name.
        /// <value>The name.</value>
        public string Name { get; set; }

        /// Gets or sets the first name.
        /// <value>The name of the first.</value>
        public string FirstName { get; set; }

        /// Gets or sets last name.
        /// <value>The name of the last.</value>
        public string LastName { get; set; }

        /// Gets or sets the organization.
        /// <value>The organization.</value>
        public string Organization { get; set; }

        /// Gets or sets the line1.
        /// <value>The line1.</value>
        public string Line1 { get; set; }

        /// Gets or sets the line2.
        /// <value>The line2.</value>
        public string Line2 { get; set; }

        /// Gets or sets the city.
        /// <value>The city.</value>
        public string City { get; set; }

        /// Gets or sets the state.
        /// <value>The state.</value>
        public string State { get; set; }

        /// Gets or sets the country code.
        /// <value>The country code.</value>
        public string CountryCode { get; set; }

        /// Gets or sets the name of the country.
        /// <value>The name of the country.</value>
        public string CountryName { get; set; }

        /// Gets or sets the postal code.
        /// <value>The postal code.</value>
        public string PostalCode { get; set; }

        /// Gets or sets the region code.
        /// <value>The region code.</value>
        public string RegionCode { get; set; }

        /// Gets or sets the name of the region.
        /// <value>The name of the region.</value>
        public string RegionName { get; set; }

        /// Gets or sets the daytime phone number.
        /// <value>The daytime phone number.</value>
        public string DaytimePhoneNumber { get; set; }

        /// Gets or sets the evening phone number.
        /// <value>The evening phone number.</value>
        public string EveningPhoneNumber { get; set; }

        /// Gets or sets the fax number.
        /// <value>The fax number.</value>
        public string FaxNumber { get; set; }

        /// Gets or sets the email.
        /// <value>The email.</value>
        public string Email { get; set; }
    }
}


text:
<?php

namespace App\Http\Controllers;

use App\LaraBin\Models\Bins\Bin;
use App\LaraBin\Models\User;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    public function show($username)
    {
        $user = User::where('username', $username)->first();

        if (!$user) {
            session()->flash('error', 'We cannot find a user with the username of [ <b>' . $username . '</b> ] Sorry.');

            return redirect()->route('home');
        }

        $bins = Bin::publicOnly()->where('user_id', $user->id)->orderBy('updated_at', 'DESC')->paginate(8);

        return view('user.show', compact('user', 'bins'));
    }
}


text:
var five = require("../lib/johnny-five.js");

// The board's pins will not be accessible until
// the board has reported that it is ready
five.Board().on("ready", function() {
  var val = 0;

  // Set pin 13 to OUTPUT mode
  this.pinMode( 13, 1 );

  // Create a loop to "flash/blink/strobe" an led
  this.loop( 100, function() {
    this.digitalWrite( 13, (val = val ? 0 : 1) );
  });
});

// Schematic
// http://arduino.cc/en/uploads/Tutorial/ExampleCircuit_bb.png


text:
[![Build Status](https://travis-ci.org/alephcloud/wai-cors.svg?branch=master)](https://travis-ci.org/alephcloud/wai-cors)

Cross-Origin Resource Sharing (CORS) For Wai
============================================

This package provides a Haskell implemenation of CORS for
[WAI](http://hackage.haskell.org/package/wai)
that aims to be compliant with
[http://www.w3.org/TR/cors](http://www.w3.org/TR/cors).

Usage
-----

The file `test/server.hs` shows how to support simple cross-origin requests (as
defined in [http://www.w3.org/TR/cors](http://www.w3.org/TR/cors)) in a
[scotty](http://hackage.haskell.org/package/scotty) application.

~~~{.haskell}
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE OverloadedStrings #-}

module Main
( main
) where

import Network.Wai.Middleware.Cors
import Web.Scotty

main ∷ IO ()
main = scotty 8080 $ do
    middleware simpleCors
    matchAny  "/" $ text "Success"
~~~

The result of following curl command will include the HTTP response
header `Access-Control-Allow-Origin: *`.

~~~{.bash}
curl -i http://127.0.0.1:8888 -H 'Origin: 127.0.0.1' -v
~~~

Documentation for more general usage can be found in the module
[Network.Wai.Middleware.Cors](http://hackage.haskell.org/package/wai-cors/docs/Network-Wai-Middleware-Cors.html).

TEST
----

Currently there is only basic support to test simple cross-origin
request from a browser.

Start server:

~~~{.bash}
cd test
runHaskell server.hs
~~~

Open the file `test/index.html` in a modern web-browser in order to run some
simple tests.


text:
<!DOCTYPE html>

        <meta charset="UTF-8">
         <meta http-equiv="X-UA-Compatible" content="IE=Edge">
         <meta name="robots" content="noindex,nofollow">
        <title>Film - <?php echo $context->movie->title ?></title>

<?php echo $context->movie->title; ?>

        <img src="<?php echo $context->movie->image; ?>" class="movieImg"/>

<?php echo $context->movie->description; ?>

        <a href="<?php echo $context->movie->content; ?>" class="movieLink">watch


text:
module Extface
  class Driver::Posiflex::Aura80 < Extface::Driver::Base::Print
    NAME = 'Posiflex (Aura 80mm)'.freeze

    DEVELOPMENT = true #driver is not ready for production (not passing all tests or has major bugs)

    CHAR_COLUMNS = 49

    include Extface::Driver::Posiflex::AuraCommands

    def handle(buffer)
      #expecting only 1 status byte, move it to receive_buffer
      rpush buffer
      return buffer.length # return number of bytes processed
    end

    def autocut(partial = true)
      push "\r\n\r\n\r\n"
      push Printer::PAPER_CUT
    end

    def check_status
      flush
      push Info::GET_PAPER_STATUS
      if status = pull(3) #wait 3 sec for data
        human_status_errors(status)
        return errors.empty?
      else
        errors.add :base, "No data received from device"
        return false
      end
    end

    private

      def human_status_errors(status_byte)
        errors.add :base, "Paper out" unless (status_byte.ord & 0x0C).zero?
      end
  end
end


text:
module.exports = function (root) {
  root = root || global
  root.expect = root.chai.expect

  beforeEach(() => {
    // Using these globally-available Sinon features is preferrable, as they're
    // automatically restored for you in the subsequent `afterEach`
    root.sandbox = root.sinon.sandbox.create()
    root.stub = root.sandbox.stub.bind(root.sandbox)
    root.spy = root.sandbox.spy.bind(root.sandbox)
    root.mock = root.sandbox.mock.bind(root.sandbox)
    root.useFakeTimers = root.sandbox.useFakeTimers.bind(root.sandbox)
    root.useFakeXMLHttpRequest = root.sandbox.useFakeXMLHttpRequest.bind(root.sandbox)
    root.useFakeServer = root.sandbox.useFakeServer.bind(root.sandbox)
  })

  afterEach(() => {
    delete root.stub
    delete root.spy
    root.sandbox.restore()
  })
}


text:
layout: page
title: Patterson Enterprises Show
date: 2016-05-24
author: Laura Trujillo
tags: weekly links, java
status: published
summary: Quisque gravida velit ut lobortis iaculis. Fusce euismod, est sed.
banner: images/banner/people.jpg
booking:
  startDate: 12/22/2019
  endDate: 12/23/2019
  ctyhocn: HSVHCHX
  groupCode: PES
published: true
---
Proin pretium interdum nibh, id lacinia ex. Vivamus ullamcorper justo vel ex rutrum euismod. Aliquam tincidunt semper faucibus. Phasellus sit amet urna a felis rutrum volutpat vitae vitae mi. Suspendisse potenti. Morbi condimentum elit tortor, in convallis metus mattis a. Sed diam massa, ultricies a enim sit amet, scelerisque vulputate velit. Nullam commodo eros eget erat scelerisque, sed rutrum elit condimentum. Integer cursus iaculis purus sed tincidunt. Sed scelerisque lorem eu cursus lacinia. Praesent magna orci, pulvinar quis gravida ac, condimentum ut elit.

1 Morbi sed lacus viverra neque vestibulum pretium
1 Aliquam fringilla quam bibendum turpis facilisis porttitor
1 Suspendisse eu diam vulputate, varius mi nec, bibendum orci.

Aenean id turpis quis felis fermentum ornare. Curabitur imperdiet quam in dui efficitur venenatis. Praesent sit amet varius ligula. Maecenas tempor, augue ut porttitor dapibus, est nunc posuere ipsum, quis vulputate nunc neque ut purus. Sed sed enim pretium, porttitor velit non, volutpat urna. Proin lectus risus, dignissim et suscipit sed, hendrerit eu arcu. Etiam commodo lorem rutrum, tempor urna quis, dictum felis. Integer vestibulum nisl non aliquet iaculis. Curabitur vestibulum nulla nibh, vitae aliquet urna mollis sit amet. Sed tellus velit, tincidunt mollis leo non, rutrum consectetur ipsum. Duis scelerisque eros at vestibulum bibendum. Etiam posuere felis non malesuada efficitur.


text:
package apple.avfoundation.struct;

import org.moe.natj.c.StructObject;
import org.moe.natj.c.ann.Structure;
import org.moe.natj.c.ann.StructureField;
import org.moe.natj.general.NatJ;
import org.moe.natj.general.Pointer;
import org.moe.natj.general.ann.Generated;
import org.moe.natj.general.ann.NInt;

@Generated
@Structure()
public final class AVSampleCursorAudioDependencyInfo extends StructObject {
    static {
        NatJ.register();
    }

    private static long __natjCache;

    @Generated
    public AVSampleCursorAudioDependencyInfo() {
        super(AVSampleCursorAudioDependencyInfo.class);
    }

    @Generated
    protected AVSampleCursorAudioDependencyInfo(Pointer peer) {
        super(peer);
    }

    @Generated
    public AVSampleCursorAudioDependencyInfo(boolean audioSampleIsIndependentlyDecodable,
            @NInt long audioSamplePacketRefreshCount) {
        super(AVSampleCursorAudioDependencyInfo.class);
        setAudioSampleIsIndependentlyDecodable(audioSampleIsIndependentlyDecodable);
        setAudioSamplePacketRefreshCount(audioSamplePacketRefreshCount);
    }

    @Generated
    @StructureField(order = 0, isGetter = true)
    public native boolean audioSampleIsIndependentlyDecodable();

    @Generated
    @StructureField(order = 0, isGetter = false)
    public native void setAudioSampleIsIndependentlyDecodable(boolean value);

    @Generated
    @StructureField(order = 1, isGetter = true)
    @NInt
    public native long audioSamplePacketRefreshCount();

    @Generated
    @StructureField(order = 1, isGetter = false)
    public native void setAudioSamplePacketRefreshCount(@NInt long value);
}


text:
#include "AsyncService.h"
#include <boost/filesystem.hpp>

enum DOWNLOADER_SERVICE_RESULT
{
	DOWNLOADER_SERVICE_RESULT_SUCCESS,
	DOWNLOADER_SERVICE_RESULT_ERROR_GENERIC,
	DOWNLOADER_SERVICE_RESULT_ERROR_CANCELLED,
	DOWNLOADER_SERVICE_RESULT_ERROR_NETWORK,
	DOWNLOADER_SERVICE_RESULT_ERROR_BADCHECKSUM,
	DOWNLOADER_SERVICE_RESULT_ERROR_BADFILESIZE
};

struct DOWNLOADER_SERVICE_COMMAND
{
	std::string						srcUrl;
	boost::filesystem::path			dstPath;
	uint32							fileSize;
	uint32							crc;
};

class CDownloaderService : public CAsyncService<DOWNLOADER_SERVICE_COMMAND, DOWNLOADER_SERVICE_RESULT>
{
public:
											CDownloaderService();
	virtual									~CDownloaderService();

	void									Download(const std::string&, const boost::filesystem::path&, uint32, uint32, const ContinuationFunction&);

	uint32									GetDownloadedSize() const;
	void									CancelDownload();

protected:
	virtual DOWNLOADER_SERVICE_RESULT		Execute(const DOWNLOADER_SERVICE_COMMAND&) override;

private:
	bool									IsDownloadRequired(const DOWNLOADER_SERVICE_COMMAND&);

	uint32									m_downloadedSize = 0;
	bool									m_downloadCancelled = false;
};


text:
//===--- TextDiagnostic.cpp - Text Diagnostic Pretty-Printing -------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/TextDiagnostic.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Locale.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>

using namespace clang;

static const enum raw_ostream::Colors noteColor =
  raw_ostream::BLACK;
static const enum raw_ostream::Colors remarkColor =
  raw_ostream::BLUE;
static const enum raw_ostream::Colors fixitColor =
  raw_ostream::GREEN;
static const enum raw_ostream::Colors caretColor =
  raw_ostream::GREEN;
static const enum raw_ostream::Colors warningColor =
  raw_ostream::MAGENTA;
static const enum raw_ostream::Colors templateColor =
  raw_ostream::CYAN;
static const enum raw_ostream::Colors errorColor = raw_ostream::RED;
static const enum raw_ostream::Colors fatalColor = raw_ostream::RED;
// Used for changing only the bold attribute.
static const enum raw_ostream::Colors savedColor =
  raw_ostream::SAVEDCOLOR;

/// Add highlights to differences in template strings.
static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str,
                                      bool &Normal, bool Bold) {
  while (1) {
    size_t Pos = Str.find(ToggleHighlight);
    OS << Str.slice(0, Pos);
    if (Pos == StringRef::npos)
      break;

    Str = Str.substr(Pos + 1);
    if (Normal)
      OS.changeColor(templateColor, true);
    else {
      OS.resetColor();
      if (Bold)
        OS.changeColor(savedColor, true);
    }
    Normal = !Normal;
  }
}

/// Number of spaces to indent when word-wrapping.
const unsigned WordWrapIndentation = 6;

static int bytesSincePreviousTabOrLineBegin(StringRef SourceLine, size_t i) {
  int bytes = 0;
  while (0<i) {
    if (SourceLine[--i]=='\t')
      break;
    ++bytes;
  }
  return bytes;
}

/// returns a printable representation of first item from input range
///
/// This function returns a printable representation of the next item in a line
///  of source. If the next byte begins a valid and printable character, that
///  character is returned along with 'true'.
///
/// Otherwise, if the next byte begins a valid, but unprintable character, a
///  printable, escaped representation of the character is returned, along with
///  'false'. Otherwise a printable, escaped representation of the next byte
///  is returned along with 'false'.
///
/// \note The index is updated to be used with a subsequent call to
///        printableTextForNextCharacter.
///
/// \param SourceLine The line of source
/// \param i Pointer to byte index,
/// \param TabStop used to expand tabs
/// \return pair(printable text, 'true' iff original text was printable)
///
static std::pair<SmallString<16>, bool>
printableTextForNextCharacter(StringRef SourceLine, size_t *i,
                              unsigned TabStop) {
  assert(i && "i must not be null");
  assert(*i<SourceLine.size() && "must point to a valid index");

  if (SourceLine[*i]=='\t') {
    assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop &&
           "Invalid -ftabstop value");
    unsigned col = bytesSincePreviousTabOrLineBegin(SourceLine, *i);
    unsigned NumSpaces = TabStop - col%TabStop;
    assert(0 < NumSpaces && NumSpaces <= TabStop
           && "Invalid computation of space amt");
    ++(*i);

    SmallString<16> expandedTab;
    expandedTab.assign(NumSpaces, ' ');
    return std::make_pair(expandedTab, true);
  }

  unsigned char const *begin, *end;
  begin = reinterpret_cast<unsigned char const *>(&*(SourceLine.begin() + *i));
  end = begin + (SourceLine.size() - *i);

  if (llvm::isLegalUTF8Sequence(begin, end)) {
    llvm::UTF32 c;
    llvm::UTF32 *cptr = &c;
    unsigned char const *original_begin = begin;
    unsigned char const *cp_end =
        begin + llvm::getNumBytesForUTF8(SourceLine[*i]);

    llvm::ConversionResult res = llvm::ConvertUTF8toUTF32(
        &begin, cp_end, &cptr, cptr + 1, llvm::strictConversion);
    (void)res;
    assert(llvm::conversionOK == res);
    assert(0 < begin-original_begin
           && "we must be further along in the string now");
    *i += begin-original_begin;

    if (!llvm::sys::locale::isPrint(c)) {
      // If next character is valid UTF-8, but not printable
      SmallString<16> expandedCP("<U+>");
      while (c) {
        expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(c%16));
        c/=16;
      }
      while (expandedCP.size() < 8)
        expandedCP.insert(expandedCP.begin()+3, llvm::hexdigit(0));
      return std::make_pair(expandedCP, false);
    }

    // If next character is valid UTF-8, and printable
    return std::make_pair(SmallString<16>(original_begin, cp_end), true);

  }

  // If next byte is not valid UTF-8 (and therefore not printable)
  SmallString<16> expandedByte("<XX>");
  unsigned char byte = SourceLine[*i];
  expandedByte[1] = llvm::hexdigit(byte / 16);
  expandedByte[2] = llvm::hexdigit(byte % 16);
  ++(*i);
  return std::make_pair(expandedByte, false);
}

static void expandTabs(std::string &SourceLine, unsigned TabStop) {
  size_t i = SourceLine.size();
  while (i>0) {
    i--;
    if (SourceLine[i]!='\t')
      continue;
    size_t tmp_i = i;
    std::pair<SmallString<16>,bool> res
      = printableTextForNextCharacter(SourceLine, &tmp_i, TabStop);
    SourceLine.replace(i, 1, res.first.c_str());
  }
}

/// This function takes a raw source line and produces a mapping from the bytes
///  of the printable representation of the line to the columns those printable
///  characters will appear at (numbering the first column as 0).
///
/// If a byte 'i' corresponds to multiple columns (e.g. the byte contains a tab
///  character) then the array will map that byte to the first column the
///  tab appears at and the next value in the map will have been incremented
///  more than once.
///
/// If a byte is the first in a sequence of bytes that together map to a single
///  entity in the output, then the array will map that byte to the appropriate
///  column while the subsequent bytes will be -1.
///
/// The last element in the array does not correspond to any byte in the input
///  and instead is the number of columns needed to display the source
///
/// example: (given a tabstop of 8)
///
///    "a \t \u3042" -> {0,1,2,8,9,-1,-1,11}
///
///  (\\u3042 is represented in UTF-8 by three bytes and takes two columns to
///   display)
static void byteToColumn(StringRef SourceLine, unsigned TabStop,
                         SmallVectorImpl<int> &out) {
  out.clear();

  if (SourceLine.empty()) {
    out.resize(1u,0);
    return;
  }

  out.resize(SourceLine.size()+1, -1);

  int columns = 0;
  size_t i = 0;
  while (i<SourceLine.size()) {
    out[i] = columns;
    std::pair<SmallString<16>,bool> res
      = printableTextForNextCharacter(SourceLine, &i, TabStop);
    columns += llvm::sys::locale::columnWidth(res.first);
  }
  out.back() = columns;
}

/// This function takes a raw source line and produces a mapping from columns
///  to the byte of the source line that produced the character displaying at
///  that column. This is the inverse of the mapping produced by byteToColumn()
///
/// The last element in the array is the number of bytes in the source string
///
/// example: (given a tabstop of 8)
///
///    "a \t \u3042" -> {0,1,2,-1,-1,-1,-1,-1,3,4,-1,7}
///
///  (\\u3042 is represented in UTF-8 by three bytes and takes two columns to
///   display)
static void columnToByte(StringRef SourceLine, unsigned TabStop,
                         SmallVectorImpl<int> &out) {
  out.clear();

  if (SourceLine.empty()) {
    out.resize(1u, 0);
    return;
  }

  int columns = 0;
  size_t i = 0;
  while (i<SourceLine.size()) {
    out.resize(columns+1, -1);
    out.back() = i;
    std::pair<SmallString<16>,bool> res
      = printableTextForNextCharacter(SourceLine, &i, TabStop);
    columns += llvm::sys::locale::columnWidth(res.first);
  }
  out.resize(columns+1, -1);
  out.back() = i;
}

namespace {
struct SourceColumnMap {
  SourceColumnMap(StringRef SourceLine, unsigned TabStop)
  : m_SourceLine(SourceLine) {

    ::byteToColumn(SourceLine, TabStop, m_byteToColumn);
    ::columnToByte(SourceLine, TabStop, m_columnToByte);

    assert(m_byteToColumn.size()==SourceLine.size()+1);
    assert(0 < m_byteToColumn.size() && 0 < m_columnToByte.size());
    assert(m_byteToColumn.size()
           == static_cast<unsigned>(m_columnToByte.back()+1));
    assert(static_cast<unsigned>(m_byteToColumn.back()+1)
           == m_columnToByte.size());
  }
  int columns() const { return m_byteToColumn.back(); }
  int bytes() const { return m_columnToByte.back(); }

  /// Map a byte to the column which it is at the start of, or return -1
  /// if it is not at the start of a column (for a UTF-8 trailing byte).
  int byteToColumn(int n) const {
    assert(0<=n && n<static_cast<int>(m_byteToColumn.size()));
    return m_byteToColumn[n];
  }

  /// Map a byte to the first column which contains it.
  int byteToContainingColumn(int N) const {
    assert(0 <= N && N < static_cast<int>(m_byteToColumn.size()));
    while (m_byteToColumn[N] == -1)
      --N;
    return m_byteToColumn[N];
  }

  /// Map a column to the byte which starts the column, or return -1 if
  /// the column the second or subsequent column of an expanded tab or similar
  /// multi-column entity.
  int columnToByte(int n) const {
    assert(0<=n && n<static_cast<int>(m_columnToByte.size()));
    return m_columnToByte[n];
  }

  /// Map from a byte index to the next byte which starts a column.
  int startOfNextColumn(int N) const {
    assert(0 <= N && N < static_cast<int>(m_byteToColumn.size() - 1));
    while (byteToColumn(++N) == -1) {}
    return N;
  }

  /// Map from a byte index to the previous byte which starts a column.
  int startOfPreviousColumn(int N) const {
    assert(0 < N && N < static_cast<int>(m_byteToColumn.size()));
    while (byteToColumn(--N) == -1) {}
    return N;
  }

  StringRef getSourceLine() const {
    return m_SourceLine;
  }

private:
  const std::string m_SourceLine;
  SmallVector<int,200> m_byteToColumn;
  SmallVector<int,200> m_columnToByte;
};
} // end anonymous namespace

/// When the source code line we want to print is too long for
/// the terminal, select the "interesting" region.
static void selectInterestingSourceRegion(std::string &SourceLine,
                                          std::string &CaretLine,
                                          std::string &FixItInsertionLine,
                                          unsigned Columns,
                                          const SourceColumnMap &map) {
  unsigned CaretColumns = CaretLine.size();
  unsigned FixItColumns = llvm::sys::locale::columnWidth(FixItInsertionLine);
  unsigned MaxColumns = std::max(static_cast<unsigned>(map.columns()),
                                 std::max(CaretColumns, FixItColumns));
  // if the number of columns is less than the desired number we're done
  if (MaxColumns <= Columns)
    return;

  // No special characters are allowed in CaretLine.
  assert(CaretLine.end() ==
         llvm::find_if(CaretLine, [](char c) { return c < ' ' || '~' < c; }));

  // Find the slice that we need to display the full caret line
  // correctly.
  unsigned CaretStart = 0, CaretEnd = CaretLine.size();
  for (; CaretStart != CaretEnd; ++CaretStart)
    if (!isWhitespace(CaretLine[CaretStart]))
      break;

  for (; CaretEnd != CaretStart; --CaretEnd)
    if (!isWhitespace(CaretLine[CaretEnd - 1]))
      break;

  // caret has already been inserted into CaretLine so the above whitespace
  // check is guaranteed to include the caret

  // If we have a fix-it line, make sure the slice includes all of the
  // fix-it information.
  if (!FixItInsertionLine.empty()) {
    unsigned FixItStart = 0, FixItEnd = FixItInsertionLine.size();
    for (; FixItStart != FixItEnd; ++FixItStart)
      if (!isWhitespace(FixItInsertionLine[FixItStart]))
        break;

    for (; FixItEnd != FixItStart; --FixItEnd)
      if (!isWhitespace(FixItInsertionLine[FixItEnd - 1]))
        break;

    // We can safely use the byte offset FixItStart as the column offset
    // because the characters up until FixItStart are all ASCII whitespace
    // characters.
    unsigned FixItStartCol = FixItStart;
    unsigned FixItEndCol
      = llvm::sys::locale::columnWidth(FixItInsertionLine.substr(0, FixItEnd));

    CaretStart = std::min(FixItStartCol, CaretStart);
    CaretEnd = std::max(FixItEndCol, CaretEnd);
  }

  // CaretEnd may have been set at the middle of a character
  // If it's not at a character's first column then advance it past the current
  //   character.
  while (static_cast<int>(CaretEnd) < map.columns() &&
         -1 == map.columnToByte(CaretEnd))
    ++CaretEnd;

  assert((static_cast<int>(CaretStart) > map.columns() ||
          -1!=map.columnToByte(CaretStart)) &&
         "CaretStart must not point to a column in the middle of a source"
         " line character");
  assert((static_cast<int>(CaretEnd) > map.columns() ||
          -1!=map.columnToByte(CaretEnd)) &&
         "CaretEnd must not point to a column in the middle of a source line"
         " character");

  // CaretLine[CaretStart, CaretEnd) contains all of the interesting
  // parts of the caret line. While this slice is smaller than the
  // number of columns we have, try to grow the slice to encompass
  // more context.

  unsigned SourceStart = map.columnToByte(std::min<unsigned>(CaretStart,
                                                             map.columns()));
  unsigned SourceEnd = map.columnToByte(std::min<unsigned>(CaretEnd,
                                                           map.columns()));

  unsigned CaretColumnsOutsideSource = CaretEnd-CaretStart
    - (map.byteToColumn(SourceEnd)-map.byteToColumn(SourceStart));

  char const *front_ellipse = "  ...";
  char const *front_space   = "     ";
  char const *back_ellipse = "...";
  unsigned ellipses_space = strlen(front_ellipse) + strlen(back_ellipse);

  unsigned TargetColumns = Columns;
  // Give us extra room for the ellipses
  //  and any of the caret line that extends past the source
  if (TargetColumns > ellipses_space+CaretColumnsOutsideSource)
    TargetColumns -= ellipses_space+CaretColumnsOutsideSource;

  while (SourceStart>0 || SourceEnd<SourceLine.size()) {
    bool ExpandedRegion = false;

    if (SourceStart>0) {
      unsigned NewStart = map.startOfPreviousColumn(SourceStart);

      // Skip over any whitespace we see here; we're looking for
      // another bit of interesting text.
      // FIXME: Detect non-ASCII whitespace characters too.
      while (NewStart && isWhitespace(SourceLine[NewStart]))
        NewStart = map.startOfPreviousColumn(NewStart);

      // Skip over this bit of "interesting" text.
      while (NewStart) {
        unsigned Prev = map.startOfPreviousColumn(NewStart);
        if (isWhitespace(SourceLine[Prev]))
          break;
        NewStart = Prev;
      }

      assert(map.byteToColumn(NewStart) != -1);
      unsigned NewColumns = map.byteToColumn(SourceEnd) -
                              map.byteToColumn(NewStart);
      if (NewColumns <= TargetColumns) {
        SourceStart = NewStart;
        ExpandedRegion = true;
      }
    }

    if (SourceEnd<SourceLine.size()) {
      unsigned NewEnd = map.startOfNextColumn(SourceEnd);

      // Skip over any whitespace we see here; we're looking for
      // another bit of interesting text.
      // FIXME: Detect non-ASCII whitespace characters too.
      while (NewEnd < SourceLine.size() && isWhitespace(SourceLine[NewEnd]))
        NewEnd = map.startOfNextColumn(NewEnd);

      // Skip over this bit of "interesting" text.
      while (NewEnd < SourceLine.size() && isWhitespace(SourceLine[NewEnd]))
        NewEnd = map.startOfNextColumn(NewEnd);

      assert(map.byteToColumn(NewEnd) != -1);
      unsigned NewColumns = map.byteToColumn(NewEnd) -
                              map.byteToColumn(SourceStart);
      if (NewColumns <= TargetColumns) {
        SourceEnd = NewEnd;
        ExpandedRegion = true;
      }
    }

    if (!ExpandedRegion)
      break;
  }

  CaretStart = map.byteToColumn(SourceStart);
  CaretEnd = map.byteToColumn(SourceEnd) + CaretColumnsOutsideSource;

  // [CaretStart, CaretEnd) is the slice we want. Update the various
  // output lines to show only this slice, with two-space padding
  // before the lines so that it looks nicer.

  assert(CaretStart!=(unsigned)-1 && CaretEnd!=(unsigned)-1 &&
         SourceStart!=(unsigned)-1 && SourceEnd!=(unsigned)-1);
  assert(SourceStart <= SourceEnd);
  assert(CaretStart <= CaretEnd);

  unsigned BackColumnsRemoved
    = map.byteToColumn(SourceLine.size())-map.byteToColumn(SourceEnd);
  unsigned FrontColumnsRemoved = CaretStart;
  unsigned ColumnsKept = CaretEnd-CaretStart;

  // We checked up front that the line needed truncation
  assert(FrontColumnsRemoved+ColumnsKept+BackColumnsRemoved > Columns);

  // The line needs some truncation, and we'd prefer to keep the front
  //  if possible, so remove the back
  if (BackColumnsRemoved > strlen(back_ellipse))
    SourceLine.replace(SourceEnd, std::string::npos, back_ellipse);

  // If that's enough then we're done
  if (FrontColumnsRemoved+ColumnsKept <= Columns)
    return;

  // Otherwise remove the front as well
  if (FrontColumnsRemoved > strlen(front_ellipse)) {
    SourceLine.replace(0, SourceStart, front_ellipse);
    CaretLine.replace(0, CaretStart, front_space);
    if (!FixItInsertionLine.empty())
      FixItInsertionLine.replace(0, CaretStart, front_space);
  }
}

/// Skip over whitespace in the string, starting at the given
/// index.
///
/// \returns The index of the first non-whitespace character that is
/// greater than or equal to Idx or, if no such character exists,
/// returns the end of the string.
static unsigned skipWhitespace(unsigned Idx, StringRef Str, unsigned Length) {
  while (Idx < Length && isWhitespace(Str[Idx]))
    ++Idx;
  return Idx;
}

/// If the given character is the start of some kind of
/// balanced punctuation (e.g., quotes or parentheses), return the
/// character that will terminate the punctuation.
///
/// \returns The ending punctuation character, if any, or the NULL
/// character if the input character does not start any punctuation.
static inline char findMatchingPunctuation(char c) {
  switch (c) {
  case '\'': return '\'';
  case '`': return '\'';
  case '"':  return '"';
  case '(':  return ')';
  case '[': return ']';
  case '{': return '}';
  default: break;
  }

  return 0;
}

/// Find the end of the word starting at the given offset
/// within a string.
///
/// \returns the index pointing one character past the end of the
/// word.
static unsigned findEndOfWord(unsigned Start, StringRef Str,
                              unsigned Length, unsigned Column,
                              unsigned Columns) {
  assert(Start < Str.size() && "Invalid start position!");
  unsigned End = Start + 1;

  // If we are already at the end of the string, take that as the word.
  if (End == Str.size())
    return End;

  // Determine if the start of the string is actually opening
  // punctuation, e.g., a quote or parentheses.
  char EndPunct = findMatchingPunctuation(Str[Start]);
  if (!EndPunct) {
    // This is a normal word. Just find the first space character.
    while (End < Length && !isWhitespace(Str[End]))
      ++End;
    return End;
  }

  // We have the start of a balanced punctuation sequence (quotes,
  // parentheses, etc.). Determine the full sequence is.
  SmallString<16> PunctuationEndStack;
  PunctuationEndStack.push_back(EndPunct);
  while (End < Length && !PunctuationEndStack.empty()) {
    if (Str[End] == PunctuationEndStack.back())
      PunctuationEndStack.pop_back();
    else if (char SubEndPunct = findMatchingPunctuation(Str[End]))
      PunctuationEndStack.push_back(SubEndPunct);

    ++End;
  }

  // Find the first space character after the punctuation ended.
  while (End < Length && !isWhitespace(Str[End]))
    ++End;

  unsigned PunctWordLength = End - Start;
  if (// If the word fits on this line
      Column + PunctWordLength <= Columns ||
      // ... or the word is "short enough" to take up the next line
      // without too much ugly white space
      PunctWordLength < Columns/3)
    return End; // Take the whole thing as a single "word".

  // The whole quoted/parenthesized string is too long to print as a
  // single "word". Instead, find the "word" that starts just after
  // the punctuation and use that end-point instead. This will recurse
  // until it finds something small enough to consider a word.
  return findEndOfWord(Start + 1, Str, Length, Column + 1, Columns);
}

/// Print the given string to a stream, word-wrapping it to
/// some number of columns in the process.
///
/// \param OS the stream to which the word-wrapping string will be
/// emitted.
/// \param Str the string to word-wrap and output.
/// \param Columns the number of columns to word-wrap to.
/// \param Column the column number at which the first character of \p
/// Str will be printed. This will be non-zero when part of the first
/// line has already been printed.
/// \param Bold if the current text should be bold
/// \param Indentation the number of spaces to indent any lines beyond
/// the first line.
/// \returns true if word-wrapping was required, or false if the
/// string fit on the first line.
static bool printWordWrapped(raw_ostream &OS, StringRef Str,
                             unsigned Columns,
                             unsigned Column = 0,
                             bool Bold = false,
                             unsigned Indentation = WordWrapIndentation) {
  const unsigned Length = std::min(Str.find('\n'), Str.size());
  bool TextNormal = true;

  // The string used to indent each line.
  SmallString<16> IndentStr;
  IndentStr.assign(Indentation, ' ');
  bool Wrapped = false;
  for (unsigned WordStart = 0, WordEnd; WordStart < Length;
       WordStart = WordEnd) {
    // Find the beginning of the next word.
    WordStart = skipWhitespace(WordStart, Str, Length);
    if (WordStart == Length)
      break;

    // Find the end of this word.
    WordEnd = findEndOfWord(WordStart, Str, Length, Column, Columns);

    // Does this word fit on the current line?
    unsigned WordLength = WordEnd - WordStart;
    if (Column + WordLength < Columns) {
      // This word fits on the current line; print it there.
      if (WordStart) {
        OS << ' ';
        Column += 1;
      }
      applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength),
                                TextNormal, Bold);
      Column += WordLength;
      continue;
    }

    // This word does not fit on the current line, so wrap to the next
    // line.
    OS << '\n';
    OS.write(&IndentStr[0], Indentation);
    applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength),
                              TextNormal, Bold);
    Column = Indentation + WordLength;
    Wrapped = true;
  }

  // Append any remaning text from the message with its existing formatting.
  applyTemplateHighlighting(OS, Str.substr(Length), TextNormal, Bold);

  assert(TextNormal && "Text highlighted at end of diagnostic message.");

  return Wrapped;
}

TextDiagnostic::TextDiagnostic(raw_ostream &OS,
                               const LangOptions &LangOpts,
                               DiagnosticOptions *DiagOpts)
  : DiagnosticRenderer(LangOpts, DiagOpts), OS(OS) {}

TextDiagnostic::~TextDiagnostic() {}

void TextDiagnostic::emitDiagnosticMessage(
    FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
    StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
    DiagOrStoredDiag D) {
  uint64_t StartOfLocationInfo = OS.tell();

  // Emit the location of this particular diagnostic.
  if (Loc.isValid())
    emitDiagnosticLoc(Loc, PLoc, Level, Ranges);

  if (DiagOpts->ShowColors)
    OS.resetColor();

  printDiagnosticLevel(OS, Level, DiagOpts->ShowColors,
                       DiagOpts->CLFallbackMode);
  printDiagnosticMessage(OS,
                         /*IsSupplemental*/ Level == DiagnosticsEngine::Note,
                         Message, OS.tell() - StartOfLocationInfo,
                         DiagOpts->MessageLength, DiagOpts->ShowColors);
}

/*static*/ void
TextDiagnostic::printDiagnosticLevel(raw_ostream &OS,
                                     DiagnosticsEngine::Level Level,
                                     bool ShowColors,
                                     bool CLFallbackMode) {
  if (ShowColors) {
    // Print diagnostic category in bold and color
    switch (Level) {
    case DiagnosticsEngine::Ignored:
      llvm_unreachable("Invalid diagnostic type");
    case DiagnosticsEngine::Note:    OS.changeColor(noteColor, true); break;
    case DiagnosticsEngine::Remark:  OS.changeColor(remarkColor, true); break;
    case DiagnosticsEngine::Warning: OS.changeColor(warningColor, true); break;
    case DiagnosticsEngine::Error:   OS.changeColor(errorColor, true); break;
    case DiagnosticsEngine::Fatal:   OS.changeColor(fatalColor, true); break;
    }
  }

  switch (Level) {
  case DiagnosticsEngine::Ignored:
    llvm_unreachable("Invalid diagnostic type");
  case DiagnosticsEngine::Note:    OS << "note"; break;
  case DiagnosticsEngine::Remark:  OS << "remark"; break;
  case DiagnosticsEngine::Warning: OS << "warning"; break;
  case DiagnosticsEngine::Error:   OS << "error"; break;
  case DiagnosticsEngine::Fatal:   OS << "fatal error"; break;
  }

  // In clang-cl /fallback mode, print diagnostics as "error(clang):". This
  // makes it more clear whether a message is coming from clang or cl.exe,
  // and it prevents MSBuild from concluding that the build failed just because
  // there is an "error:" in the output.
  if (CLFallbackMode)
    OS << "(clang)";

  OS << ": ";

  if (ShowColors)
    OS.resetColor();
}

/*static*/
void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS,
                                            bool IsSupplemental,
                                            StringRef Message,
                                            unsigned CurrentColumn,
                                            unsigned Columns, bool ShowColors) {
  bool Bold = false;
  if (ShowColors && !IsSupplemental) {
    // Print primary diagnostic messages in bold and without color, to visually
    // indicate the transition from continuation notes and other output.
    OS.changeColor(savedColor, true);
    Bold = true;
  }

  if (Columns)
    printWordWrapped(OS, Message, Columns, CurrentColumn, Bold);
  else {
    bool Normal = true;
    applyTemplateHighlighting(OS, Message, Normal, Bold);
    assert(Normal && "Formatting should have returned to normal");
  }

  if (ShowColors)
    OS.resetColor();
  OS << '\n';
}

void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
  SmallVector<char, 128> AbsoluteFilename;
  if (DiagOpts->AbsolutePath) {
    auto Dir = SM.getFileManager().getDirectory(
        llvm::sys::path::parent_path(Filename));
    if (Dir) {
      // We want to print a simplified absolute path, i. e. without "dots".
      //
      // The hardest part here are the paths like "<part1>/<link>/../<part2>".
      // On Unix-like systems, we cannot just collapse "<link>/..", because
      // paths are resolved sequentially, and, thereby, the path
      // "<part1>/<part2>" may point to a different location. That is why
      // we use FileManager::getCanonicalName(), which expands all indirections
      // with llvm::sys::fs::real_path() and caches the result.
      //
      // On the other hand, it would be better to preserve as much of the
      // original path as possible, because that helps a user to recognize it.
      // real_path() expands all links, which sometimes too much. Luckily,
      // on Windows we can just use llvm::sys::path::remove_dots(), because,
      // on that system, both aforementioned paths point to the same place.
#ifdef _WIN32
      SmallString<4096> DirName = (*Dir)->getName();
      llvm::sys::fs::make_absolute(DirName);
      llvm::sys::path::native(DirName);
      llvm::sys::path::remove_dots(DirName, /* remove_dot_dot */ true);
#else
      StringRef DirName = SM.getFileManager().getCanonicalName(*Dir);
#endif
      llvm::sys::path::append(AbsoluteFilename, DirName,
                              llvm::sys::path::filename(Filename));
      Filename = StringRef(AbsoluteFilename.data(), AbsoluteFilename.size());
    }
  }

  OS << Filename;
}

/// Print out the file/line/column information and include trace.
///
/// This method handlen the emission of the diagnostic location information.
/// This includes extracting as much location information as is present for
/// the diagnostic and printing it, as well as any include stack or source
/// ranges necessary.
void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
                                       DiagnosticsEngine::Level Level,
                                       ArrayRef<CharSourceRange> Ranges) {
  if (PLoc.isInvalid()) {
    // At least print the file name if available:
    FileID FID = Loc.getFileID();
    if (FID.isValid()) {
      const FileEntry *FE = Loc.getFileEntry();
      if (FE && FE->isValid()) {
        emitFilename(FE->getName(), Loc.getManager());
        OS << ": ";
      }
    }
    return;
  }
  unsigned LineNo = PLoc.getLine();

  if (!DiagOpts->ShowLocation)
    return;

  if (DiagOpts->ShowColors)
    OS.changeColor(savedColor, true);

  emitFilename(PLoc.getFilename(), Loc.getManager());
  switch (DiagOpts->getFormat()) {
  case DiagnosticOptions::Clang: OS << ':'  << LineNo; break;
  case DiagnosticOptions::MSVC:  OS << '('  << LineNo; break;
  case DiagnosticOptions::Vi:    OS << " +" << LineNo; break;
  }

  if (DiagOpts->ShowColumn)
    // Compute the column number.
    if (unsigned ColNo = PLoc.getColumn()) {
      if (DiagOpts->getFormat() == DiagnosticOptions::MSVC) {
        OS << ',';
        // Visual Studio 2010 or earlier expects column number to be off by one
        if (LangOpts.MSCompatibilityVersion &&
            !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2012))
          ColNo--;
      } else
        OS << ':';
      OS << ColNo;
    }
  switch (DiagOpts->getFormat()) {
  case DiagnosticOptions::Clang:
  case DiagnosticOptions::Vi:    OS << ':';    break;
  case DiagnosticOptions::MSVC:
    // MSVC2013 and before print 'file(4) : error'. MSVC2015 gets rid of the
    // space and prints 'file(4): error'.
    OS << ')';
    if (LangOpts.MSCompatibilityVersion &&
        !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
      OS << ' ';
    OS << ':';
    break;
  }

  if (DiagOpts->ShowSourceRanges && !Ranges.empty()) {
    FileID CaretFileID = Loc.getExpansionLoc().getFileID();
    bool PrintedRange = false;

    for (ArrayRef<CharSourceRange>::const_iterator RI = Ranges.begin(),
         RE = Ranges.end();
         RI != RE; ++RI) {
      // Ignore invalid ranges.
      if (!RI->isValid()) continue;

      auto &SM = Loc.getManager();
      SourceLocation B = SM.getExpansionLoc(RI->getBegin());
      CharSourceRange ERange = SM.getExpansionRange(RI->getEnd());
      SourceLocation E = ERange.getEnd();
      bool IsTokenRange = ERange.isTokenRange();

      std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
      std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);

      // If the start or end of the range is in another file, just discard
      // it.
      if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
        continue;

      // Add in the length of the token, so that we cover multi-char
      // tokens.
      unsigned TokSize = 0;
      if (IsTokenRange)
        TokSize = Lexer::MeasureTokenLength(E, SM, LangOpts);

      FullSourceLoc BF(B, SM), EF(E, SM);
      OS << '{'
         << BF.getLineNumber() << ':' << BF.getColumnNumber() << '-'
         << EF.getLineNumber() << ':' << (EF.getColumnNumber() + TokSize)
         << '}';
      PrintedRange = true;
    }

    if (PrintedRange)
      OS << ':';
  }
  OS << ' ';
}

void TextDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) {
  if (DiagOpts->ShowLocation && PLoc.isValid())
    OS << "In file included from " << PLoc.getFilename() << ':'
       << PLoc.getLine() << ":\n";
  else
    OS << "In included file:\n";
}

void TextDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
                                        StringRef ModuleName) {
  if (DiagOpts->ShowLocation && PLoc.isValid())
    OS << "In module '" << ModuleName << "' imported from "
       << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
  else
    OS << "In module '" << ModuleName << "':\n";
}

void TextDiagnostic::emitBuildingModuleLocation(FullSourceLoc Loc,
                                                PresumedLoc PLoc,
                                                StringRef ModuleName) {
  if (DiagOpts->ShowLocation && PLoc.isValid())
    OS << "While building module '" << ModuleName << "' imported from "
      << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
  else
    OS << "While building module '" << ModuleName << "':\n";
}

/// Find the suitable set of lines to show to include a set of ranges.
static llvm::Optional<std::pair<unsigned, unsigned>>
findLinesForRange(const CharSourceRange &R, FileID FID,
                  const SourceManager &SM) {
  if (!R.isValid()) return None;

  SourceLocation Begin = R.getBegin();
  SourceLocation End = R.getEnd();
  if (SM.getFileID(Begin) != FID || SM.getFileID(End) != FID)
    return None;

  return std::make_pair(SM.getExpansionLineNumber(Begin),
                        SM.getExpansionLineNumber(End));
}

/// Add as much of range B into range A as possible without exceeding a maximum
/// size of MaxRange. Ranges are inclusive.
static std::pair<unsigned, unsigned>
maybeAddRange(std::pair<unsigned, unsigned> A, std::pair<unsigned, unsigned> B,
              unsigned MaxRange) {
  // If A is already the maximum size, we're done.
  unsigned Slack = MaxRange - (A.second - A.first + 1);
  if (Slack == 0)
    return A;

  // Easy case: merge succeeds within MaxRange.
  unsigned Min = std::min(A.first, B.first);
  unsigned Max = std::max(A.second, B.second);
  if (Max - Min + 1 <= MaxRange)
    return {Min, Max};

  // If we can't reach B from A within MaxRange, there's nothing to do.
  // Don't add lines to the range that contain nothing interesting.
  if ((B.first > A.first && B.first - A.first + 1 > MaxRange) ||
      (B.second < A.second && A.second - B.second + 1 > MaxRange))
    return A;

  // Otherwise, expand A towards B to produce a range of size MaxRange. We
  // attempt to expand by the same amount in both directions if B strictly
  // contains A.

  // Expand downwards by up to half the available amount, then upwards as
  // much as possible, then downwards as much as possible.
  A.second = std::min(A.second + (Slack + 1) / 2, Max);
  Slack = MaxRange - (A.second - A.first + 1);
  A.first = std::max(Min + Slack, A.first) - Slack;
  A.second = std::min(A.first + MaxRange - 1, Max);
  return A;
}

/// Highlight a SourceRange (with ~'s) for any characters on LineNo.
static void highlightRange(const CharSourceRange &R,
                           unsigned LineNo, FileID FID,
                           const SourceColumnMap &map,
                           std::string &CaretLine,
                           const SourceManager &SM,
                           const LangOptions &LangOpts) {
  if (!R.isValid()) return;

  SourceLocation Begin = R.getBegin();
  SourceLocation End = R.getEnd();

  unsigned StartLineNo = SM.getExpansionLineNumber(Begin);
  if (StartLineNo > LineNo || SM.getFileID(Begin) != FID)
    return;  // No intersection.

  unsigned EndLineNo = SM.getExpansionLineNumber(End);
  if (EndLineNo < LineNo || SM.getFileID(End) != FID)
    return;  // No intersection.

  // Compute the column number of the start.
  unsigned StartColNo = 0;
  if (StartLineNo == LineNo) {
    StartColNo = SM.getExpansionColumnNumber(Begin);
    if (StartColNo) --StartColNo;  // Zero base the col #.
  }

  // Compute the column number of the end.
  unsigned EndColNo = map.getSourceLine().size();
  if (EndLineNo == LineNo) {
    EndColNo = SM.getExpansionColumnNumber(End);
    if (EndColNo) {
      --EndColNo;  // Zero base the col #.

      // Add in the length of the token, so that we cover multi-char tokens if
      // this is a token range.
      if (R.isTokenRange())
        EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts);
    } else {
      EndColNo = CaretLine.size();
    }
  }

  assert(StartColNo <= EndColNo && "Invalid range!");

  // Check that a token range does not highlight only whitespace.
  if (R.isTokenRange()) {
    // Pick the first non-whitespace column.
    while (StartColNo < map.getSourceLine().size() &&
           (map.getSourceLine()[StartColNo] == ' ' ||
            map.getSourceLine()[StartColNo] == '\t'))
      StartColNo = map.startOfNextColumn(StartColNo);

    // Pick the last non-whitespace column.
    if (EndColNo > map.getSourceLine().size())
      EndColNo = map.getSourceLine().size();
    while (EndColNo &&
           (map.getSourceLine()[EndColNo-1] == ' ' ||
            map.getSourceLine()[EndColNo-1] == '\t'))
      EndColNo = map.startOfPreviousColumn(EndColNo);

    // If the start/end passed each other, then we are trying to highlight a
    // range that just exists in whitespace. That most likely means we have
    // a multi-line highlighting range that covers a blank line.
    if (StartColNo > EndColNo) {
      assert(StartLineNo != EndLineNo && "trying to highlight whitespace");
      StartColNo = EndColNo;
    }
  }

  assert(StartColNo <= map.getSourceLine().size() && "Invalid range!");
  assert(EndColNo <= map.getSourceLine().size() && "Invalid range!");

  // Fill the range with ~'s.
  StartColNo = map.byteToContainingColumn(StartColNo);
  EndColNo = map.byteToContainingColumn(EndColNo);

  assert(StartColNo <= EndColNo && "Invalid range!");
  if (CaretLine.size() < EndColNo)
    CaretLine.resize(EndColNo,' ');
  std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,'~');
}

static std::string buildFixItInsertionLine(FileID FID,
                                           unsigned LineNo,
                                           const SourceColumnMap &map,
                                           ArrayRef<FixItHint> Hints,
                                           const SourceManager &SM,
                                           const DiagnosticOptions *DiagOpts) {
  std::string FixItInsertionLine;
  if (Hints.empty() || !DiagOpts->ShowFixits)
    return FixItInsertionLine;
  unsigned PrevHintEndCol = 0;

  for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
       I != E; ++I) {
    if (!I->CodeToInsert.empty()) {
      // We have an insertion hint. Determine whether the inserted
      // code contains no newlines and is on the same line as the caret.
      std::pair<FileID, unsigned> HintLocInfo
        = SM.getDecomposedExpansionLoc(I->RemoveRange.getBegin());
      if (FID == HintLocInfo.first &&
          LineNo == SM.getLineNumber(HintLocInfo.first, HintLocInfo.second) &&
          StringRef(I->CodeToInsert).find_first_of("\n\r") == StringRef::npos) {
        // Insert the new code into the line just below the code
        // that the user wrote.
        // Note: When modifying this function, be very careful about what is a
        // "column" (printed width, platform-dependent) and what is a
        // "byte offset" (SourceManager "column").
        unsigned HintByteOffset
          = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second) - 1;

        // The hint must start inside the source or right at the end
        assert(HintByteOffset < static_cast<unsigned>(map.bytes())+1);
        unsigned HintCol = map.byteToContainingColumn(HintByteOffset);

        // If we inserted a long previous hint, push this one forwards, and add
        // an extra space to show that this is not part of the previous
        // completion. This is sort of the best we can do when two hints appear
        // to overlap.
        //
        // Note that if this hint is located immediately after the previous
        // hint, no space will be added, since the location is more important.
        if (HintCol < PrevHintEndCol)
          HintCol = PrevHintEndCol + 1;

        // This should NOT use HintByteOffset, because the source might have
        // Unicode characters in earlier columns.
        unsigned NewFixItLineSize = FixItInsertionLine.size() +
          (HintCol - PrevHintEndCol) + I->CodeToInsert.size();
        if (NewFixItLineSize > FixItInsertionLine.size())
          FixItInsertionLine.resize(NewFixItLineSize, ' ');

        std::copy(I->CodeToInsert.begin(), I->CodeToInsert.end(),
                  FixItInsertionLine.end() - I->CodeToInsert.size());

        PrevHintEndCol =
          HintCol + llvm::sys::locale::columnWidth(I->CodeToInsert);
      }
    }
  }

  expandTabs(FixItInsertionLine, DiagOpts->TabStop);

  return FixItInsertionLine;
}

/// Emit a code snippet and caret line.
///
/// This routine emits a single line's code snippet and caret line..
///
/// \param Loc The location for the caret.
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
void TextDiagnostic::emitSnippetAndCaret(
    FullSourceLoc Loc, DiagnosticsEngine::Level Level,
    SmallVectorImpl<CharSourceRange> &Ranges, ArrayRef<FixItHint> Hints) {
  assert(Loc.isValid() && "must have a valid source location here");
  assert(Loc.isFileID() && "must have a file location here");

  // If caret diagnostics are enabled and we have location, we want to
  // emit the caret.  However, we only do this if the location moved
  // from the last diagnostic, if the last diagnostic was a note that
  // was part of a different warning or error diagnostic, or if the
  // diagnostic has ranges.  We don't want to emit the same caret
  // multiple times if one loc has multiple diagnostics.
  if (!DiagOpts->ShowCarets)
    return;
  if (Loc == LastLoc && Ranges.empty() && Hints.empty() &&
      (LastLevel != DiagnosticsEngine::Note || Level == LastLevel))
    return;

  // Decompose the location into a FID/Offset pair.
  std::pair<FileID, unsigned> LocInfo = Loc.getDecomposedLoc();
  FileID FID = LocInfo.first;
  const SourceManager &SM = Loc.getManager();

  // Get information about the buffer it points into.
  bool Invalid = false;
  StringRef BufData = Loc.getBufferData(&Invalid);
  if (Invalid)
    return;

  unsigned CaretLineNo = Loc.getLineNumber();
  unsigned CaretColNo = Loc.getColumnNumber();

  // Arbitrarily stop showing snippets when the line is too long.
  static const size_t MaxLineLengthToPrint = 4096;
  if (CaretColNo > MaxLineLengthToPrint)
    return;

  // Find the set of lines to include.
  const unsigned MaxLines = DiagOpts->SnippetLineLimit;
  std::pair<unsigned, unsigned> Lines = {CaretLineNo, CaretLineNo};
  for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
                                                  E = Ranges.end();
       I != E; ++I)
    if (auto OptionalRange = findLinesForRange(*I, FID, SM))
      Lines = maybeAddRange(Lines, *OptionalRange, MaxLines);

  for (unsigned LineNo = Lines.first; LineNo != Lines.second + 1; ++LineNo) {
    const char *BufStart = BufData.data();
    const char *BufEnd = BufStart + BufData.size();

    // Rewind from the current position to the start of the line.
    const char *LineStart =
        BufStart +
        SM.getDecomposedLoc(SM.translateLineCol(FID, LineNo, 1)).second;
    if (LineStart == BufEnd)
      break;

    // Compute the line end.
    const char *LineEnd = LineStart;
    while (*LineEnd != '\n' && *LineEnd != '\r' && LineEnd != BufEnd)
      ++LineEnd;

    // Arbitrarily stop showing snippets when the line is too long.
    // FIXME: Don't print any lines in this case.
    if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint)
      return;

    // Trim trailing null-bytes.
    StringRef Line(LineStart, LineEnd - LineStart);
    while (!Line.empty() && Line.back() == '\0' &&
           (LineNo != CaretLineNo || Line.size() > CaretColNo))
      Line = Line.drop_back();

    // Copy the line of code into an std::string for ease of manipulation.
    std::string SourceLine(Line.begin(), Line.end());

    // Build the byte to column map.
    const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop);

    // Create a line for the caret that is filled with spaces that is the same
    // number of columns as the line of source code.
    std::string CaretLine(sourceColMap.columns(), ' ');

    // Highlight all of the characters covered by Ranges with ~ characters.
    for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
                                                    E = Ranges.end();
         I != E; ++I)
      highlightRange(*I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts);

    // Next, insert the caret itself.
    if (CaretLineNo == LineNo) {
      CaretColNo = sourceColMap.byteToContainingColumn(CaretColNo - 1);
      if (CaretLine.size() < CaretColNo + 1)
        CaretLine.resize(CaretColNo + 1, ' ');
      CaretLine[CaretColNo] = '^';
    }

    std::string FixItInsertionLine = buildFixItInsertionLine(
        FID, LineNo, sourceColMap, Hints, SM, DiagOpts.get());

    // If the source line is too long for our terminal, select only the
    // "interesting" source region within that line.
    unsigned Columns = DiagOpts->MessageLength;
    if (Columns)
      selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine,
                                    Columns, sourceColMap);

    // If we are in -fdiagnostics-print-source-range-info mode, we are trying
    // to produce easily machine parsable output.  Add a space before the
    // source line and the caret to make it trivial to tell the main diagnostic
    // line from what the user is intended to see.
    if (DiagOpts->ShowSourceRanges) {
      SourceLine = ' ' + SourceLine;
      CaretLine = ' ' + CaretLine;
    }

    // Finally, remove any blank spaces from the end of CaretLine.
    while (!CaretLine.empty() && CaretLine[CaretLine.size() - 1] == ' ')
      CaretLine.erase(CaretLine.end() - 1);

    // Emit what we have computed.
    emitSnippet(SourceLine);

    if (!CaretLine.empty()) {
      if (DiagOpts->ShowColors)
        OS.changeColor(caretColor, true);
      OS << CaretLine << '\n';
      if (DiagOpts->ShowColors)
        OS.resetColor();
    }

    if (!FixItInsertionLine.empty()) {
      if (DiagOpts->ShowColors)
        // Print fixit line in color
        OS.changeColor(fixitColor, false);
      if (DiagOpts->ShowSourceRanges)
        OS << ' ';
      OS << FixItInsertionLine << '\n';
      if (DiagOpts->ShowColors)
        OS.resetColor();
    }
  }

  // Print out any parseable fixit information requested by the options.
  emitParseableFixits(Hints, SM);
}

void TextDiagnostic::emitSnippet(StringRef line) {
  if (line.empty())
    return;

  size_t i = 0;

  std::string to_print;
  bool print_reversed = false;

  while (i<line.size()) {
    std::pair<SmallString<16>,bool> res
        = printableTextForNextCharacter(line, &i, DiagOpts->TabStop);
    bool was_printable = res.second;

    if (DiagOpts->ShowColors && was_printable == print_reversed) {
      if (print_reversed)
        OS.reverseColor();
      OS << to_print;
      to_print.clear();
      if (DiagOpts->ShowColors)
        OS.resetColor();
    }

    print_reversed = !was_printable;
    to_print += res.first.str();
  }

  if (print_reversed && DiagOpts->ShowColors)
    OS.reverseColor();
  OS << to_print;
  if (print_reversed && DiagOpts->ShowColors)
    OS.resetColor();

  OS << '\n';
}

void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints,
                                         const SourceManager &SM) {
  if (!DiagOpts->ShowParseableFixits)
    return;

  // We follow FixItRewriter's example in not (yet) handling
  // fix-its in macros.
  for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
       I != E; ++I) {
    if (I->RemoveRange.isInvalid() ||
        I->RemoveRange.getBegin().isMacroID() ||
        I->RemoveRange.getEnd().isMacroID())
      return;
  }

  for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
       I != E; ++I) {
    SourceLocation BLoc = I->RemoveRange.getBegin();
    SourceLocation ELoc = I->RemoveRange.getEnd();

    std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
    std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);

    // Adjust for token ranges.
    if (I->RemoveRange.isTokenRange())
      EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, LangOpts);

    // We specifically do not do word-wrapping or tab-expansion here,
    // because this is supposed to be easy to parse.
    PresumedLoc PLoc = SM.getPresumedLoc(BLoc);
    if (PLoc.isInvalid())
      break;

    OS << "fix-it:\"";
    OS.write_escaped(PLoc.getFilename());
    OS << "\":{" << SM.getLineNumber(BInfo.first, BInfo.second)
      << ':' << SM.getColumnNumber(BInfo.first, BInfo.second)
      << '-' << SM.getLineNumber(EInfo.first, EInfo.second)
      << ':' << SM.getColumnNumber(EInfo.first, EInfo.second)
      << "}:\"";
    OS.write_escaped(I->CodeToInsert);
    OS << "\"\n";
  }
}